Confluence and JIRA have a great plugin system at their core that allows you to install collections of actions, Spring beans (Confluence), jobs, etc. as discrete plugins. Confluence supports hot-deploying these plugins so they can be added, removed, or upgraded without bringing down the application. This capability is so powerful that internally we are moving more and more functionality into plugins as a way to organise our codebase and keep it tightly-focused and agile.
Wanting this same functionality in Struts 2, but enhanced to support versioned transitive plugin dependencies (plugin A uses services from plugin B which uses services from plugin C) that are automatically resolved and verified at runtime, I wrote the first cut at an OSGi plugin for Struts 2. This plugin allows you to group your actions and services into different jars, namely OSGi bundles.
The goal is for the Struts 2 developer, very little OSGi knowledge will be required and eventually the plugin will include features like a bundle management GUI (also deployed as a Struts 2 bundle) and integration with Spring’s OSGi project to make bundle development as easy and close to normal development practices as possible.
From a technical point of view, what I did was create an OsgiConfigurationProvider, which starts an embedded Felix OSGi container and automatically loads bundles it finds in ‘WEB-INF/classes/bundles’. It loads the bundle’s struts.xml configuration file, inserting packages into the main Struts 2 configuration. The plugin also overrides the ObjectFactory (delegating to a user-defined ObjectFactory) so that classes can be loaded from bundles if not found in the application’s classloader. Finally, to enable Velocity resources to be resolved, it adds a Velocity ResourceLoader that also iterates through the bundles looking for the desired template. The basic integration pattern is what is used today in the Confluence source code.
Therefore, from a user perspective, they will need to add a few lines to
web.xml to enable the configuration provider:
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> <init-param> <param-name>configProviders</param-name> <param-value>org.apache.struts2.osgi.OsgiConfigurationProvider</param-value> </init-param> </filter>
Then, drop the Struts 2 OSGi plugin in your
/WEB-INF/lib and the plugin is fully installed.
More information can be found on the plugin’s documentation. The plugin is still in the very early stages and as such, isn’t ready for production as it hasn’t been tested heavily and is missing key features. Still, it, along with Spring’s OSGi project, holds a lot of potential to make truely hot-deployable web applications easier for everyone.