One of the major perks of working on the Developer Relations team in San Francisco is that we sit right next to the Integration team, whose job — in a sense — is to test and push the limits of our plugin development platform, through the process of developing useful cross-product components. They are often the first consumers of new enhancements to the plugin framework, the SDK and other core Atlassian technologies, and their experience forms the basis of the best practices we try to promote to the plugin development community.
While the Integration team was developing the Universal Plugin Manager last year, one thing I overheard a lot of complaints about was how difficult it can be to debug OSGi-related problems. The Plugin SDK automatically installs the Felix Web Console into your host application when using atlas-run or atlas-debug, but it falls somewhat short as a debugging tool when you’re trying to fix package or service dependency resolution issues, and it doesn’t work correctly in all of our products.
Another related issue I’ve noticed from developer questions on our forums is that the way our plugin framework encapsulates OSGi and Spring DM — and the relevant magical incantations required in a plugin’s pom.xml and atlassian-plugin.xml configuration — can be pretty opaque to developers. So, when the Integration team lead, John, came up with the idea of making “a better Felix Web Console,” I jumped on it as a 20% project to benefit plugin developers.
So, months later, and after 20% of my time becoming something more on the order of 120%, I’m happy to finally announce the availability of UPM 1.3, which includes the new OSGi tab. Here’s a quick tour of the OSGi tab running in Confluence:
The new OSGi tab looks very similar to the “Manage” tab, but instead of listing installed plugins it lists OSGi bundles. Bundles that are in the ACTIVE state (for example, enabled plugins) are shown in blue, inactive bundles are shown in grey. Clicking a bundle’s title shows all of the bundle’s header information (extracted from its OSGi manifest), as well as the services it provides and uses:
Here I’ve opened Confluence’s System Bundle, which exports a huge number of packages. In the Felix Web Console, a bundle’s package listings are a bit difficult to navigate, particularly when there are thousands of them. My main goal was to improve on that:
So, you can see at a glance which bundles depend on each exported package. Better still, you can click to navigate between interdependent bundles. What happens when I click on the link for the UPM’s bundle?
Ta-da, through the magic of jQuery and AUI it pops open the bundle for the UPM. (Can you tell I’m quite satisfied with myself?) Now what’s this, the UPM imports packages from other bundles? Let’s click.
Indeed, you can quickly see that the UPM relies on components provided not only by the system bundle, but by the REST plugin, the Atlassian Template Renderer and other pieces of conveniently modular functionality. If any of the declared imports were unresolved and not optional, causing plugin enablement to fail, they would show here in red.
Service dependencies are equally clear and easy to navigate, again showing which bundles provide and consume each service, as well as the object classes that each service exposes:
Finally, as suggested by Matt Doar, I included a search function to quickly find OSGi bundles with any manifest headers or service references matching a given string:
UPM 1.3 has the same platform requirements as 1.2.x, namely Plugins 2.6, SAL 2.2, and REST 2.2. That translates to compatibility with the latest released versions of Confluence, Fisheye and Crucible, and the upcoming releases of Jira and Bamboo. UPM 1.3 isn’t yet bundled with any product releases, so to use it in development of your plugin right now, the easiest technique is probably to declare it as a <pluginArtifact> in your plugin’s pom.xml.
Finally, one piece of highly recommended reading: how to set OSGi manifest instructions in your plugin. The SDK and plugin framework are typically smart enough to infer an appropriate set of Import-Package entries for simple plugins, but for more sophisticated plugins we’ve found it’s important to explicitly specify what packages your plugin imports and exports. Knowing how to do this, together with using the new UPM OSGi tab, should make it much faster to develop sophisticated, modular plugins.