Disclaimer: This post is a post about my opinions and experiences with the pipeline portal application, Cocoon. This disclaimer is included to disclaim any possibility that I may be wrong about this. Period. :-P
What is Apache Cocoon?
On paper its an impressive framework to construct a web application around practically any source medium, dynamic or otherwise. Cocoon is largely based on the XML philosophy (that everything has to be extremely complex and difficult to use to store simple information (citation)).
Cocoon also can generate a user interface for a component application from the component applications XML output.
Apache Cocoon is a modular framework where each module is broken into a "Block". Each block enhances the Cocoon functionality in some respect. For the purposes of this post I will say that most of my experience is with the JSR-168 Portal block. This block is supposed to be a JSR-168 compliant portal application which can process and render portlets.
What is a Portlet?
I'm not going to go into much detail here but as an overview a Portlet is a Java application which renders into a HTML container within a Portal application. From the users perspective a Portlet is a small box on a HTML page, and that a Portal can contain many portlets and organise how they are rendered, positioned, etc. Portlets can be a little long winded to design complex applications with but they've never caused my hair to fall out.
What is my opinion?
Ah the important question! Well let's start at the beginning. I am currently working on a project which involves employing a Portlet application on a currently running copy of Cocoon at a client organisation. Our software was originally designed for Pluto (another Apache project - a very nice stand alone Portal application) as it was a JSR-168 portal and we were assured that if it ran in Pluto it would also run on Cocoon.
Our first problems came into effect when we tried to install our Portlet. The copy of Cocoon we downloaded most of the example configurations did not work. We had a time trying to determine how to install the Portlet, we eventually found out we have to edit several XML files and configure the Portal Block to recognise our web application. I am not a fan of the XML philosophy but I can recognise that XML has its uses. This took a while to figure out and complete.
Our portlet application was still not being recognised, we were confused. After several hours of looking for fixes we found out that we had to delete certain .jars located around the package we downloaded from the Cocoon project website. I am actually very confused why the Cocoon installation we had required so many broken components. The Apache project are smart people so there is probably an explaination for it, but I've yet to find it.
Further more, we had serious problems replicating our configuration. We ended up just copying our entire tomcat directory between workstations for other developers to work with it. Even just suppling our entire web application directory, including Cocoon and all the other installed applications to another work station yielded no positive results. My scalp becoming a mess of torn off skin after two days I was beginning to dislike Cocoon.
Now we're at a point where Cocoon recognises and runs our portlet. However we've hit a wall. Our application uses several Servlets and Java Server Page components to modularise computation and keep coupling down to a minimum.
Inter portlet/servlet communication is arrived out by the use of the session to hand other components the data they require for processing. To quote from the JavaDoc of the JSR-168 PortletSession interface specification:
All objects stored in the session using the APPLICATION_SCOPE must be available to all the portlets, servlets and JSPs that belongs to the same portlet application and that handles a request identified as being a part of the same session. Objects stored in the session using the PORTLET_SCOPE must be available to the portlet during requests for the same portlet window that the objects where stored from. Attributes stored in the PORTLET_SCOPE are not protected from other web components of the portlet application. They are just conveniently namespaced.
The crux of the problem is as follows. We diagnosed the problem and determined that the session ID sent to our Servlet components was entirely different to that of the Portlet components. Interestingly we found that there are two IDs sent, one of which is identical in the requests of both the Servlet and Portlet. The other is completely different - and that is the one Cocoon and our Servlets are using. I read a conversation from one of the Portal block developers on the Cocoon project where he was arguing that Cocoon should support the specification but doesn't. The argument for why it doesn't is largely based on the "session=bad" argument. This has made it very hard for us to develop for and has cost me, and my company significant effort.
A further issue we encountered is less of a Cocoon problem (as we weren't playing nice ourselves) but more of an example of very curious behaviour. Cocoon uses precision buffering system where it calculates the exact output length from the Portlet and only prints that exact length. Our client uses international characters that will be required to be printed in the output. The behaviour it exhibits when encountering these characters is very curious. Each one of these characters takes up two bytes in its output buffer (which admittedly all of these should be made into HTML entities). The interesting point is that Cocoon doesn't count the byte length of the buffer but instead just the number of characters that are supposed to be printed and it takes this number as being the byte length of the output.
I am hating Cocoon right now. It was a pain to set up, a pain to maintain, and a pain to develop for. If you are looking at Portal applications I would recommend Pluto.