Introducing Jahia OSGi modules
As you may know, Jahia's development team is hard at work on the next version of our CMS and in this post I'd like to highlight one of the major upcoming changes: the introduction of OSGi modules.
Before I go any further into the details of how we did this, let me explain the rationale. Since Jahia 6.5, we’ve introduced a new module system that makes it easy to build packages that can extend content definitions or provide new logic for page components (or even simply provide back-end services). But there were a few open problems that we had (yet) to address. Mostly some issues with the module lifecycle that were mostly due to the way that modules were packaged, such as the fact that they were exploded at deployment and that libraries were copied into Jahia’s WEB-INF/lib directory. This made some modules’ runtime deployment tricky and also made undeployment of modules more complex that we wanted. Also, Jahia’s module deployment and packaging were not based on a real module standard but rather on our own interpretation of how to package and deploy a web application part. OSGi solves all these problems and introduces a lot of new possibilities while also being a mature and standardized technology that has more than proven it’s worth in the enterprise world.
For those of you unfamiliar with OSGi, it is mostly a technology that brings true modularity to Java applications, allowing runtime deployment and undeployment of classes, libraries and services, and it is even capable of running multiple versions of the same library side-by-side. It achieves this by a clever usage of class loaders, by defining what a JAR exports and imports, along with the versions of the shared resources. It also provides a lot more such as a dynamic service lookup and registration, wiring frameworks such as OSGi Blueprint (based on Spring Dynamic modules) or out of the box services such as console shells or logging services.
An OSGi bundle is basically a JAR with specific headers in it’s META-INF/MANIFEST.MF file. These headers contains things such as the bundle’s symbolic name (Bundle-SymbolicName), the version (Bundle-Version), and the most important ones being the export and import package directives (Import-Package and Export-Package). These directives declares which Java packages the bundle exports (ie makes available to others) and which version it has, and which Java packages are necessary for the bundle to be able to install and run (ie package dependencies). In OSGi packages are used as the entity for controlling dependencies, which makes sense since inside a JAR everything is always in a package (except for the root resources). So even if you are only packaging non-code files such as property files or other resources (static HTML, JSPs), they will be in a subdirectory that could be interpreted as a package (provided it adheres to the package naming conventions of course).
Package dependencies are an important part of understanding how to bundle logic and resources into OSGi modules, so it will probably be the major new thing that Jahia module developers will have to get familiar with, but despite the initial learning curve, it quickly becomes a habit, offers a lot of control, and is “fail-fast”. “Fail-fast” means that things will break early, usually at deployment time, which is much better than at runtime, since you can quickly check the wiring of your different modules while still developing it, instead of discovering issues once the module goes into production.
OSGi bundles will be the new default way of packaging your modules in the upcoming version of Jahia, and all our tools have been adapted for this new format, including the Jahia Studio, the Jahia Maven Plugin and even our FixApplier tool. This new format allows you to do a lot more than previously possible with modules, since OSGi bundles can also be packaged with Activator classes, that are called upon module startup and shutdown, or if they registered listeners, at any point in any module’s lifecycle. We have actually re-implemented Jahia’s internal deployers as OSGi bundles, so as you can see the architecture becomes a lot more modular and powerful.
With the power of OSGi’s fully dynamic deployment could come some wiring complexity, since any service may be registered or unregistered at any time. Handling all this yourself could be quite complex but fortunately OSGi already provides a few ways to get around this, ranging from the simple ServiceTracker interface all the way to OSGi’s BluePrint specification. OSGi BluePrint is a wiring specification that was actually based on the Spring Framework’s Dynamic Modules. So much so that the reference implementation of OSGi BluePrint is actually Spring’s contribution to OSGi of their dynamic module implementation. We have chosen to integrate this implementation since we were already offering the possibility to use Spring wiring descriptors inside Jahia modules, so this makes for a smooth migration path.
Speaking of migration, this was a very important aspect of our integration of OSGi as a module system. We set a very ambitious internal goal when working on this new technology : that most modules should work out of the box without any binary or source modification. This was a real technical challenge since this involved a lot of different technologies that can be embedded inside a Jahia module, ranging from content definition files, JSP with tag libraries, custom actions, listeners, code libraries (such as Hibernate), Spring beans (that may be exposed to other modules) and many other dynamic integrations. OSGi on the other hand is a technology that tries to declare dependencies as much as possible at deployment time, so we had to develop a “transformer” to be able to transform Jahia WAR modules into OSGi JAR bundles at deployment time. I am very happy to be able to say that we have already tested this quite extensively and despite fringe complex modules that may require some manual adjustments, the wide majority of modules we could get our hands on worked out of the box. Of course we strongly encourage any developers with existing Jahia modules to get their hands dirty with the code source trunk as soon as possible to make sure that they can test their modules, or even get started on migrating them to native OSGi bundles.
Migrating a Jahia module project to a real OSGi bundle is quite trivial, especially since the format hasn’t changed much. The main differences are : the contents of the src/main/webapp must be moved to the src/main/resources directory and the Maven project descriptor file (pom.xml) must be adjusted to change the packaging from WAR to an OSGi bundle. We will even be providing a Maven goal in our Jahia Maven plugin that will help automate the project transformation should you need to do it on a lot of modules. As this was not complex to do, we have already converted all of Jahia’s own modules to a fully native OSGi bundle format so you will also have plenty of examples to look at.
Of course we did not write an OSGi framework ourselves, but instead decided to integrate with the Apache Felix framework that is already widely used and well suited for server-side projects. Felix comes with a lot of interesting things out of the box such as a Web Console interface, a command line interface and the possibility to be embedded easily. Of course we are using the latest stable version of the framework, so this means that you will be able to use all the features of the OSGi 4.3 specification. For example we already use the new capabilities headers to declare and require content definitions inside Jahia modules. This way you can easily make sure that a module will not be started if there isn’t another module installed that provides those content definitions.
Another open source project that we have integrated with is the OPS4j PAX Web project. They provide a bundle that provides a JSP engine that can be embedded to be able to dispatch directly to JSP files that are inside of an OSGi JAR bundle. This frees us from needing to explode JARs on the disk as we did in previous versions of Jahia. So in the new version there is no disk deployment for modules anymore. This change is important since it really improves the modularity and especially the undeployment of modules, making it trivial to deploy changes, even while the server is running. I can tell you that this change was really fun to work with, even in the initial stages, and clearly continues our focus on making working on Jahia modules as productive as possible. I think that once people get used to the new way of doing things, they will also see all the possibilities that it opens up.
So that’s it for a quick introduction of a major change in the upcoming version of Jahia. As you see we’ve worked very hard to make sure that everything is as seamless as possible, while bringing you the best and latest frameworks to build your solutions using Jahia. But we also want to hear back from you, especially if you would like more details, examples, since we could easily follow-up this blog post with anything you might be interested in. So please feel free to comment below or contact us.
Author : Serge Huber
Serge Huber is co-founder and CTO of Jahia. He is a member of the Apache Software Foundation and Chair of the Apache Unomi project management committee as well as a co-chair of the OASIS Customer Data Platform Specification.