JPF Part 1 – A lightweight alternative to OSGi?
25. February 2010
When developing web applications it has always been a challenge how to plug in customer specific extensions and integrations without invading the inner guts of the web application too much. This not only concerns the source code, it is quite easy to keep customer specific sources out of the application’s trunk, the main problems usually arise when thinking about deployment strategies.
One of our rules here at Catalysts says that we must not ship anything that does not come from our continuous integration server. We just don’t want to end up sitting at the customers site and trying to figure out why something doesn’t work as expected that has just worked minutes ago on some developer’s box. Operating systems tend to become “polluted” very quickly during development and after installing a bunch of weird SDKs you can never predict what you are actually linking your code against on your local machine.
Our CI agents run on clean virtualized hosts and always build the sources from scratch, that way we can be pretty sure that all the needed dependencies are bundled with our application and are not just there by accident on one of the developer’s boxes.
Now this rule has strong implications on how customer specific extensions and integrations can be shipped. Our continuous integration server bundles the web application into a ready-to-install WAR file, that of course doesn’t include any of those extensions. Naive thinking, this leaves us two possible options:
- configuring a customer specific build for each customer that generates a WAR file including all the customer specific modifications.
- doing separate builds for the web application and the extensions and patching everything together during deployment.
Option 1 isn’t really practicable as we would end up maintaining a vast amount of build configurations that actually more or less build the same thing. This would just be a waste of resources in every aspect, hence leaving us only option 2. Then again, the above mentioned rule pretty much restricts us on how to interpret patching. According to that rule we must not touch the WAR file and the bundled extension module generated by the CI server for anything else than copying to the deployment location. Simply unzipping the WAR file and putting the extensions in is not a feasible strategy for us.
As a matter of fact, we were looking for something that can autodiscover and pick up jars outside the web root at runtime so that we just need to copy our plugins next to the WAR file. After some googeling we stumbled upon JPF which
provides a runtime engine that dynamically discovers and loads “plug-ins”. A plug-in is a structured component that describes itself to JPF using a “manifest”. JPF maintains a registry of available plug-ins and the functions they provide (via extension points and extensions).
One major goal of JPF is that the application (and its end-user) should not pay any memory or performance penalty for plug-ins that are installed, but not used. Plug-ins are added to the registry at application start-up or while the application is running but they are not loaded until they are called.
This project was inspired by and continues to be influenced by the Eclipse Platform – an open source Java IDE and “rich client” GUI applications platform.
The plug-in architecture used by Eclipse was taken as the basic model for JPF in early 2004. JPF is can be considered as an attempt to “decouple” the plug-in framework from Eclipse 2.x for use in any Java project. Note that although Eclipse plug-ins are visually very similar to JPF plug-ins, they are NOT compatible and thus can’t be used together.
Now that sounded like the perfect match. Getting it up and running was pretty straight forward, the difficult part however was to let it play nicely with the Spring Framework.
Stay tuned for a follow-up blog post on how we did the Spring Integration.
Tags: Java, Java Plugin Framework, Spring
