Thursday, October 6, 2011

Ugrading to clojure 1.3.0 causes Unable to resolve symbol: print-doc in this context

I upgraded to Clojure 1.3.0 and got this when I tried to run lein swank
Caused by: java.lang.RuntimeException: Unable to resolve symbol: print-doc in this context
        at clojure.lang.Util.runtimeException(Util.java:156)
        at clojure.lang.Compiler.resolveIn(Compiler.java:6720)
        at clojure.lang.Compiler.resolve(Compiler.java:6664)
        at clojure.lang.Compiler.analyzeSymbol(Compiler.java:6625)
        at clojure.lang.Compiler.analyze(Compiler.java:6198)
        ... 93 more
Turns out the culprit is swank-clojure. I had version 1.2.1 but had to upgrade to 1.3.3. Be sure to manually delete the old version as lein deps didn't delete it.

See the topoged project file for an example

Friday, September 23, 2011

Top ten things I learned at Liferay West Coast Symposium 2011

I spent the last couple of days in mostly sunny Anaheim attending the Liferay West Coast Symposium 2011. I also attended last year and found it so useful that I went again this year.

Unlike last year, this year I am going to write a list of the highlights and lowlights of the conference. Without further ado, the list of thing I learned at the symposium

1. Liferay has some good press

As is customary in those sorts of things, the conference started off with a "rah-rah" keynote about how wonderful Liferay is, what a good company they are and other PR related stuff. Normally, I would even comment on this as it happens at every conference everywhere. The details are somewhat different but the message is the same: "Feel good about being associated with us".

However, I had thought during this PR blitz about Liferay as a open-source product and a company that makes money by giving away its primary product. Keep in mind, they do make money as a self-funded and profitable company. The message is that this company and product is competing quite well with all the big players and is gaining market share (according to Gartner) where others are falling out of the picture.

With all this, there is the real stigma of open-source associated with Liferay, evidenced by our on-going negotiations with them to license the product. The proprietary companies have done a great job of down-playing the value of open-source while pushing technologies that lock a customer to a their vendor. Liferay's success in following business model of building a product that is non-proprietary is unique in a world of Oracle, IBM and other companies that see a portal as a way to lock a customer into a vertical and expensive stack.

Lessons learned:

  • Liferay is a profitable company
  • Using Liferay allows the customer to choose the underlying stack
  • We need to do a better job of getting the word out that Liferay is an enterprise level ecosystem and not just an open-source product
Speaking of doing a better job of getting the word out ...

2: Documentation (or the lack thereof)

If there is one failing of Liferay it is in the documentation department. Of course this is a common problem with open-source projects but Liferay is positioning itself to be an enterprise player. One things enterprise customers expect is documentation and support. Liferay's support has been as good if not singularly better that other companies support and we haven't paid them a dime yet.

Their documentation has been really lacking and it showed at the conference. I attended several sessions where the question of documentation was raised. Sometimes people wanted to follow-up on the current topic or some other topic was raised in passing that people were not familiar with. The answer was never "read the fine manual" but was some variation of "check out the source" or "we are working on that". The problem with the lack of documentation is there are a lot features available that customers do not know about. This is one of my main reasons for returning to the symposium this year was to learn what I didn't even know about.

Consider to getting into Disneyland for free and spending your whole day on "Its a Small World". Liferay is a such and extensive product with so many things available for developers, UI people, and content contributors but we don't even know we what are not using.

There are some good things happening with documentation. First, the whole documentation site has been revamped. In the past, the documentation has been hard to access and to find what you were looking for. The new site is better organized but still lacking in actual content (see my service builder section below). There more in-depth articles are needed as well as clearer examples.

Second, there is a new book out Liferay in Action: The Official Guide to Liferay Portal Development and from what I saw, it looks like a must have for Liferay developers.

The chapters include:

  • Chapter 3, "A data-driven portlet made easy"
  • Chapter 4, "MVC the Liferay way"
  • Chapter 5, "Providing your own site design with themes and layout templates"
  • Chapter 9, "Liferay architecture and extension points"
  • Chapter 10, "A tour of Liferay APIs"
It looks like this book will go a long way to correct the documentation problems with Liferay. Lessons learned:
  • Documentation continues to be a challenge, but is being addressed both online and in print
  • Much of the current documentation consists of both source code and samples
Speaking of source code ...

3: Liferay is on github

Git is a newer source control system as are subversion and cvs. The github site provides a certal place to host software projects in much the same way source forge does. Liferay has put the source code in github in the liferay project. The advantage is that it is easier to find the source code, especially the sample code, as well as providing a simpler mechanism for submitting patches back to Liferay.

There are also lots of sample portlets in the repository which provide a good starting point for a new project. Lessons learned:

  • Liferay source is now more accessible on github
  • The sample code can now be easily found

4: Staging

Liferay 6 introduced the concept of staging. This allows the web-site designer to work on updates to the website without affecting what the users sees and then publishing the changes once they are completed. This is a great feature that we will be able to take advantage of with out deployments. It will allow us to make the changes we need to make and get them verified before the night of the production deployment. During deployment we can just publish the changes that have already been verified which will save us all a great deal of time.

Liferay 6.1 takes this idea a step further by allowing multiple staging versions at the same time. The example given was to be working on the Christmas design and the Valentines design at the same time, all while the users are still seeing the current design. This will allow the designers greater flexibility to work in the site without having to worry how the incremental changes appear to the users. Once the work is done, the site can be published.

What was not brought up was how staging works with different version of plugins. It seems like different version of the same war file would need to exist on the server if the new designs require new portlets, themes etc. This should not be a big deal, but will need to be taken into consideration. This that need to be considered is the name of the portlets and the categories so it is clear in the Add Application which portlet is being added.

Lessons learned:

  • Staging can be used to safely make incremental changed to a site without impacting users
  • Staging may require multiple version of plugins
Speaking of plugins ...

5: Liferay Developer Studio and Liferay IDE

The Liferay Developer Studio and IDE provide some tools to create plugins in a simple wizard way. There are wizards for creating portlets and for creating hooks. The IDE runs in Eclipse and the Studio is built on Eclipse giving them some good tools to work with.

The projects produced are ant based. This is not too problematic in itself, but it is inconvient. A lot of projects, and all of our projects, run under maven. Converting from ant to maven is normally not a huge effort, not of an inconvience. The problem with the projects generated is that the ant build files depend on files outside the projects. This makes it difficult to convert to maven. It also hinders allowing other people to work on the projects without a full liferay EXT environment.

I started paying attention during the sessions and the only time I saw either is when they were being demonstrated. In almost every session, the presenter was using straight Eclipse on a Mac. A few were using Textmate but no one was using the Liferay tools. For what its worth, I didn't see any Netbeans nor EMACS.

Lesson learned:

  • The Liferay IDE and Developer Studio have some good tools
  • Mostly they are used for getting started on a project and then back to your regular IDE.
  • Put all JSPs in a single hook by themselves. Service hooks go in their own war file.

6: Mobile

Liferay 6.0 has detection for mobile devices. Liferay 6.1 improves upon it.

Lessons learned:

  • Liferay is actively trying to make mobile work well on the platform.

7: OpenSocial

There was a demonstration of OpenSocial gadgets. They work well and interact with portlets but seem to be simplier to produce.

Lessons learned:

  • Not really a lesson but a question: Can OpenSocial gadgets replace some out our portlets?

8: Alloy UI

Alloy UI is Liferay's answer to JQuery. It provides the unified look and feel for the console and can be used in custom plugins. While nice, the lack of documentation and the tighter binding to Liferay make me want to stick with JQuery.

Lessons Learned:

  • Ties us to the Liferay Portal
  • Documentation is lacking

9: Lifeay Sync

Similar to Dropbox, it allows for sharing of files across devices and the Liferay Document Library. The real strength is to allow content contributors to automatically have their files updated to the server so there is no upload step needed. This can be of great benefit when there are lots of documents being needing to be added to the server.

10: Liferay Marketplace

Liferay is creating a new server called Marketplace. This is the give the same sort of functionality that the App Store gives to iPhones. It allows developers to upload plugins and people can easily find and download them. It looks like it could be a good idea.

Tuesday, August 16, 2011

Clojure Patterns: cons, car and cdr

My first look at Clojure came very close to being my last. Coming from a background of both Lisp and Java, Clojure sounded like a good way to get the benefits of functional programming in a JVM environment. As with a lot of people I have become increasingly frustrated with object-oriented programming. Too many things are still either too hard or simply too "boiler-plate", things that a functional paradigm addresses more cleanly.

As with any new language, it is good to poke it with a stick. Accordingly, I fired up a REPL and tried a few command just to see what happens. My first session went something like:

user> (+ 1 2 3)
6
user> (cons 1 2)
java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer (NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:5440)
at clojure.lang.Compiler.eval(Compiler.java:5391)
at clojure.core$eval.invoke(core.clj:2382)

Seriously?, a Lisp that cannot cons? And with that I shut down the REPL and went on with my life.

Sometime later a friend of mine re-introduced me to Clojure and I took a deeper look at it. There are a lot of things to recommend the language, the "broken" cons not-with-standing. The concurrency model, the lazy model and sequences in general are both well thought out and implemented.

However, as a new language there are a lot of questions out there that boil down to "how do I implement X in Clojure"? Languages like Java have a lot of materials out there on that exact subject, often referred to as design patterns. By following the established patterns one can implement "better" code.

Some would say that design patterns are to overcome language defects. While that may be true in some cases, that is certainly not the driving force behinds these ideas. Design patterns have been around for a long time with lots of names. The Greeks had a golden ratio. Today we have the "16 inch on center" pattern. In construction, it is common to build walls with 2x4s 16 inches apart. Doing so is not to overcome a deficiency in lumber, but is a well-established technique for making sturdy walls. In addition, it makes the wiring, plumbing, insulation and sheet rock work together properly as well. The benefit is felt even years later when a person needs to work on the wall.

The same idea applies to software. If software is built using accepted patterns, that software has a better chance to being able to integrate into systems today and to be maintained in the future.

With that in mind, I will be presenting some patterns for use in Clojure. These patterns will be garnered from personal experience, from the Clojure core and from answers to questions which people pose in various places around the web.

The first pattern will be an anti-pattern: cons, car and cdr. Since these do not exist as expected in the language, what is the proper way to implement these ideas in Clojure? First a quick reference table.

Patterns Quick Reference
IdeaCONSCARCDR
A cons cell or a pair (def pair [1 2]) (first pair) or (pair 0) (second pair) or (pair 1)
A sequence or ISeq like list, vector, set or map (def sq (cons 4 [3 2 1])) (first sq) (rest sq)
An arbitrary data structure Use either a built in clojure data structure or a Java object Access depends on the structure Access depends on the structure
Cons Cell or Pair

As noted before the cons cell does not exist a generic data structure in Clojure. If you want to create a simple pair of values, one recommended way to do it is with a vector. A vector allows you to quickly create a structure to hold one or more values that can be quickly accessed by index, much like an array.

A vector can be created using the vector function or by surroundings the values in square brackets []. Using vectors is fast and also allows for expansion from just a pair of values to any n-tuple of values. Retrieving the values can be done in several ways including:

  • Functions first and second
  • Using the vector itself as a function and getting the values by index
  • Treating the vector as a sequence and using map, reduce and filter.
user=> (def pair [1 2])
#'user/pair
user=> (first pair)
1
user=> (pair 0)
1
user=> (second pair)
2
user=> (pair 1)
2
user=> (reduce + pair)
3
Sequence or ISeq

In Lisp the basic abstraction is the List is is simply a linked list of cons cells. The head of each cell is the value and the tail is a link to the next cons cell in the list. In Clojure, the basic abstration is the Sequence implemented with the ISeq interface. This allows Clojure to have multiple higher-level data structures with different semantics that implement this interface and can be accessed in similar ways. These data structures include lists, sets, vectors and maps. All have different uses yet can all be accessed in classic fashion using functions like map, reduce and filter.

The cons function in both Lisp and Clojure adds an element to the beginning of a list or sequence. In Lisp, the result is a new list while in Clojure the result is a new sequence. The concrete implementation of the sequence does not matter as much as the fact the it implements ISeq and is thus able to be processed as expected.

user=> (def sq (cons 4 [3 2 1]))
#'user/sq
user=> sq
(4 3 2 1)
user=> (first sq)
4
user=> (rest sq)
(3 2 1)
user=> (class [3 2 1])
clojure.lang.PersistentVector
user=> (class sq)
clojure.lang.Cons
Data Structures

In Lisp it is possible to build arbitrary data structures like trees using cons cells. Clojure is built on the JVM and therefore has access to any data structure via the java interop. There are also a set of data structures built in that are immutable and are therefore well suited to the language.

At this point there will not be any examples of using data structures as the general usage of data structures in the language is beyond the scope of a discussion of cons, car and cdr. As specific patterns are discussed examples appropriate to the pattern will be given.

Conclusion

While Clojure is missing a basic Lisp form, it turns out that by using higher abstractions the same tasks can be accomplished in a more efficient manner. It is unfortunate that the language is missing the cons cell just to avoid the principle of least astonishment for people coming from Lisp.

Next time will be a discussion of recursion in Clojure because there is an unexpected twist in how it is implemented.

Friday, February 11, 2011

Validate error missing in portlet render phase - Spring Community Forums

Validate error missing in portlet render phase - Spring Community Forums I fought this for a couple of days before coming across this article. The issue is a simple one: errors that were added to the bindingResult either with a validator or with the rejectValue call were not showing up in the JSP form:errors tags. The solution is to add the ModelAttribute for the form command object to the SessionAttributes so it survives from the action phase to the render phase.

Wednesday, January 26, 2011

Using HTML5 Input types with Spring 3.0 form tags

HTML5 supports various input types including email, url and tel. There is a lack of documentation for using these new types with the Spring form taglib. After trial and error I tried:
<form:input type="tel" alt="Home Phone" path="homePhone"/>
which surpisingly enough produced the expected code:
<input type="tel" alt="Home Phone" value="" name="homePhone" id="homePhone">
It is nice when something follows the principle of least astonishment.