dissabte, 2 d’abril del 2011

Liferay Portal Server: avoiding use of extension (Part 1)

I've been working for some years around Liferay Portal Server. I really think it's a great portal solution, but, from a developer's point of view, there is something I, personally, really don't like: the extension environment.
Basically, what bothers me about extension is:

  • there is no effective hot deploy solution
  • I can't organize my project with the granularity I'd like. I mean, if I need to modify two Liferay's embedded portlets, I'd like to have two wars, each one for the corresponding portlet to be modified.
Of course, Liferay's team has been working on it and, specially from release 6, there has been some improvements, but still there is one clue to keep in mind while developing with Liferay: "avoid using extension as much as you can".
The introduction of hooks, long time ago, brought some hope about this, but still you can't modify some really important things on portlets, that is: tiles definitions and struts configurations.

Time ago when working on Liferay 5.1.2, I came across these thoughts and developed an extension over Liferay's code that allowed me to override Liferay's Tiles definitions, Struts configurations, and Spring beans, just using hooks. Of course, from Liferay 6 you can already overwrite Liferay's Spring services, so I'm gonna share how to override the Tiles and Struts parts of Liferay using hooks.
This module, if it can be called so, is called Zeep 'oTron, and so, I call hooks getting profit of this enhancement, zeepoHooks. I'm not gonna get into details on the origin of these names (I'd better not!), but that's just the names we thought for it! ;)

Things we need to know

Before starting our solution there are some things we need to keep in mind:

  1. This has been developed to use with Tomcat
  2. The place where we can get access to Liferay's Struts and Tiles configurations is Liferay's Main Servlet class
  3. Once Struts configs get loaded, all those mappings get freezed, so we will have to develop a new Struts module config factory to avoid this freeezing, so that we can add new configs after initial load.
  4. Since, probably, we will need to add new classes with our new Struts configs, we will need to be able to add those new classes to the classloader

Points 2 and 3 have some important consequences. In first place, when Struts resolves a navigation, the reading of the corresponding configurations is not synchronized, so if we modify them on runtime, there could be some errors on running requests. So be aware of this if using this on production environments.
On second place, we are just gonna add classes to the class loader,  therefore, those classes that are already instantiated and remain in JVM's head will not probably be modified as you would expect; by the way, I've never run into any problems with those "Struts classes".

A Solution


Our solution is quiet simple, we will just create a HookHotDeployer that feeds our new methods in Liferay's Main Servlet so that this can load all the necessary stuff.

In next entries I will explain how to develop that hotdeployer, how to modify Liferay's Main Servlet, and any thing you could need to understand the process.
Finally, I will provide sample code for this solution.

Keep reading about this in Part 2!