Monday, March 12, 2012

Ever wonder how Liferay keeps track of it's WAR'ed Portlets

Liferay is a portlet container. With the distribution that comes with Tomcat bundled in by default, it deployed it's main portal into tomcat's ROOT. This main portal will have all the bits and pieces to manage portlets deployed subsequently as WAR files, which without much surprised gets deployed into separate webapps with it's own application context default to the war file name being dumped into Liferay's deploy directory, conveniently located one level above the tomcat home within Liferay distribution. To manage those Portlets located under different webapps, Liferay needs some way to tie the Portlet's Servlet path to it's ServletContext.

Ever wonder how Liferay does this?

Have the opportunity to dig around a bit with Liferay's code and guess what, this is how Liferay does it. It has a ServletContextPool which is basically something like a static factory singleton with a bunch of public static methods accessing a single instance of itself. Servlet corresponding to a particular Portlet when initialized will just make use of those relevant static methods to stick it's context path and ServletContext into a map.

You might wonder how is this possible when all webapps are being deployed to have it's own ClassLoader. Which means webapp1 will have it's own copy of ServletContextPool which will be separate instance from webapp2. Although they are accessing static methods they are still separate instance due to webapp1 and webapp2 have separate classloaders that do not allow them to see each other's classes.

But ClassLoaders are hierarchical and most app servers will eventually inherit a global ClassLoader, Tomcat is not difference. What Liferay does is it package ServetContextPool into portal-service.jar which unsurprisingly located in Tomcat's lib/ext folder which happens to be Tomcat's glabal classpath. Jars located there will be visible to all web application.

Interesting. Pretty simple and straight forward way of getting it done. Does this kind of implementation sounds familiar? Ring any bells? I'm guessing this is somewhat similar way SLF4j (Standard Log4j) decide which logging implementation to hook up in runtime.

No comments:

Post a Comment