Liferay Portal & OSGi

Over the past several months I've been working on integrating an OSGi framework into Liferay Portal. The reasons for doing so are varied but include solutions to app server/servlet container dependency, library version conflicts, runtime module lifecycle, advanced extensibility, and so on.

If you are not familliar with OSGi, I recommend visiting the OSGi web site, and in particular reading the Benefits of Using OSGi.

The first publicly available code of this integration is available as an OSGi branch on my fork of the liferay-portal project on github.

The url of the branch is: https://github.com/rotty3000/liferay-portal/tree/OSGi

I'd like to encourage anyone having an interest in this work to clone the branch and send me feature improvements, bug fixes, etc, via git pull request, or even to just send me comments here.

 

Things I've done to date:

  • I'm using Eclipse Equinox 3.7 (but it works with any 4.1 or greater implementation of OSGi with no code changes, I tested Knopflerfish 3.2.0 and it worked very well, I'm sure Felix would work equally well).
  • Published all the services and beans of the portal's spring context as services in the framework so they can be used by bundles.
  • Developed a management portlet available in the control panel where the portal administor can add/remove/start/stop/update bundles, see all the bundle headers, all the service registrations and all service references of any bundle. (I'd like to eventually add bundle dependency graphing as well).
  • Make sure logging works (this can be tricky in OSGi due to libraries not due to OSGi).
  • Setup an auto deploy listener that will inspect any jar/war file dropped into the portal deploy folder that are OSGi bundles and automatically install them into the framework (and try to start them).
  • Setup a bridge Servlet which is wired into the OSGi HttpService to provide HttpServlet request dispatching for any servlets or jsps registered in the framework. (This feature depends on a bundle I created which I'm going to release in the comming days, in an OSGi branch of my fork of the liferay-plugins repository. The bundle depends on the eclipse equinox http servlet package which is available in the Equinox 3.7 zip.)
  • I've successfully tested various code modification scenarios such as replacing a service implementation and replacing a Util implementation, with all the virtues of OSGi bundle lifecycle goodness.
  • I've successfully deployed and used the recently released Gemini Blueprint implementation of the OSGi Blueprint specification (which you might call Spring for OSGi). It's a simple matter of deploying the 3 main bundles.
  • I've added BND lib to the portal so that it can be used for various OSGi packaging tasks.

Things I'd like to do next:

  • Make some changes to the Plugins SDK so that plugins can (optionally) be generated as OSGi bundles.
  • Support deploying the various bundle-ized plugins into the framework.
  • Support all the spring wiring of ServiceBuilder services found in plugins correctly.
  • Setup a portal packaging system so that we can bundle as set of bundles/plugins so there is no need to assemble and install them manually.
  • Modify the Liferay repository mechanism so that it supports bundles and implements either auto update or auto detectiong of possible updates for bundles in the repository (and also resolves/downloads dependencies).

 

Here are a couple of images of the OSGi Admin portlet.

List of bundles:

View of a Bundle:

 

I'll be presenting this work in a workshop at the upcoming West Coast Symposium in Anaheim on 21-22 of September.

I hope to hear your thoughs on this and maybe to discuss it with you at WCS.

Blogs
Whohoo! Nice!

Ray, is this correct URL to see the modifications? https://github.com/rotty3000/liferay-portal/compare/master...OSGi

Thank you.

-- tom
As a guy that prepares and sells solutions based on Liferay I want to ask what do we gonna get from "Liferay+OSGi"?
hey ray, could you make your images viewable for guests. I am getting a permission error now
@Tomáš, yes it is!

@Szymon, my primary goal is to eliminate the dependency on j2ee/servlet specs and app server behaviors for support of hot deploy plugins. Basically, if Liferay could be a plain war, with no global scope interactions/changes needed, it would be better for everyone. OSGi can give us that and more.

@ jelmer, Sorry, should be fixed now!
Does Liferay+OSGi helps us to deploy Liferay in Goggle app engine ?
Not immediately, but eventually it would make it more feasible to attempt it.

There are a number of restrictions that Liferay would have to overcome, naturally the one I mentioned is one of the toughest, the global classloader dependency for plugins.
But even after than is solved, we still need to address: "an app cannot spawn threads, write data to the local file system or make arbitrary network connections", but besides this, and by far the most difficult task would be the persistence tier, which for Liferay is heavily customized hibernate/SQL. App Engine only provides JDO and JPA, which we don't yet support either of.
Very nice! Thanks, Ray.
I just published the liferay-plugins OSGi branch with a few plugins to test out some of the features, such as http bridge support and example, service wrapper example, spring dm example, and blueprint example.

https://github.com/rotty3000/liferay-plugins/tree/OSGi
Truly interesting, I have to take a look.

Brian Chan did mention OSGi development direction and reasons behind it year ago at European Symposium and now we see where you are going.

Good work.
Ray, how deep do you want to go with the extensibility?

Have you thought about loading/overriding/adding Struts+Tiles configs/classes, servlet filters, exposing portlets services ... also from the OSGi context - where it could be redefined by a custom module.

And another idea - querying services/pojos in the OSGi context based on the current context in the portal (companyId/name, groupId/name) ?
Ray, how is this going to reflect on ServiceBuilder ? In regards to the notion of 2 non-related spring contexts (portlet / portal) that use different classloaders - SpringUtil.loadContext() for loading context from spring.configs locations is ok for testing Portal only, but for testing both Portlet services that implicitly use Portal services ... it is not so trivial. This is actually third time I'm doing that, I did it every time differently, learning from past mistakes...
At least from my perspective the model does not change from the current model one iota in the first generations. I also don't see a reason to change it since the OSGi blueprint spec is virtually a one to one mapping of what we're currently doing, except in standardized way.
be interesting also ? for Vaadin portlets if UI modules could be added/removed on the fly

http://vaadin.com/wiki/-/wiki/Main/Creating%20a%20Modular%20Vaadin%20Application%20with%20OSGi
Yup! I don't see any reason why they couldn't. I'm still working on the request handling delegation model (which will heavily factor in when working with third party libs like this). Right now the behavior is pretty raw but I figure it won't be more than a month or two (working on this only part time at the present) and I'll have that sorted out.
I cloned git://github.com/rotty3000/liferay-portal.git locally and after a successful build and starting the server, I still do NOT see the OSGi Admin in the control panel. Is there something else I need to do in order to see this in action?

Thanks!
You need to use the OSGi branch on my fork emoticon It should be in your clone if you pulled all the branches (which I think is typically the default).

That branch is a little old about 2-3 weeks, but it's still very functional.
just a clarification, i dont see any equinox jars or any other OSGi supported framework jars in the web-inf/lib of the Liferay OSGi server that i build from your github repo. is the bnd.jar the one which does the provisioning of bundles ? Can you please explain how bundles are processed and which jars are key for it ? just to understand the core architecture of it.
Liferay ships with equinox.jar that will appear in the WEB-INF/lib folder. This jar provides both the osgi apis as well as the equinox implementation. You could just as easily change this jar for Felix or Knopflerfish, or any OSGi implementation that supports the Framework API, as well as the BundleStartLevel API.

You will find in portal.properties under the ## OSGi heading properties related to the configuration of the framework.

I would like to stick with pure OSGi APIs in order for it to be possible to maintain this implementation agnostic support. It currently is, and should remain possible to swap out the OSGi implementation for any that support the OSGi 4.3 or higher standard.

Deployment of OSGi bundles is implemented in two ways currently. You can drop bundles into the standard deploy folder and an OSGiAutoDeployListener which will identify bundles and install them (this is in trunk already) OR you can upload them directly via the OSGi Admin portlet if you have my OSGi branch (since this portlet is not in trunk).

On portal startup, Liferay's OSGiServiceUtil class will dynamically locate and load the first Framework implementation it finds in its classpath. When initializing the Framework it will use the properties defined in portal(-ext).properties to setup it's environment. The interaction between the portal and Framework will continue to be controlled completely through this class, such as install/update/remove/start/stop/adjust run levels, etc.

The BND jar is only used for handling of OSGi header parsing in two places a) during build time for the portal core, and b) during auto deploy to check if a plugin is an OSGi bundle.
I'm so happy to see OSGi integration with Liferay, even in alpha stages. I'd love to see Liferay itself split into separate OSGi bundles but I'd imagine that's years and years away.
Thanks for your feedback Jevon!

I should have some OSGi related content coming out very soon! I hope you find it interesting and ideally useful.
Hi Ray,
Could you give me an updated status of our branch ? it is stable? it is sync with 6.1 version?
I've been working in a vaadin + osgi + tycho product a couple of months. After reading your article, I think that integrating liferay could be a nice path to follow...
regards,
Cristiano