June 18th, 2011

On OSGi, Spring and Eclipse Virgo

Review of OSGi Web Development, using Eclipse Virgo Tomcat Server and the Spring Framework.

— Matthew Fellows —

It has been several months since I’ve started using OSGi to build Web Applications with Spring and Eclipse Virgo, and I thought it would be a good time to review the various learning’s to date and present my opinions, in particular on OSGi and Virgo.

It is a work in-progress, but I hope this works out to be a good resource for OSGi \ Virgo programmers and a starting point for some discussion around the below points – I invite comments…

Eclipse Virgo

In summary, Virgo (now Virgo Tomcat Server to differentiate between it’s sibling Virgo Jetty Server) is neat little Tomcat web server embedded as an OSGi module within Equinox. It uses the OSGi extender pattern to create a bridge between Equinox and Tomcat so that Web artifacts (WARs) inherit the same properties and lifecycle as a regular OSGi bundle – meaning they can be hot-deployed at runtime – with little effort from the developer.

It has some excellent features, including out-of-the-box declarative services support, the ability to specify dependencies on entire bundles or libraries (instead of tediously entering in billions of error prone Import-Package statements – use with caution) using Import-Bundle and Import-Library manifest headers, OSGi configuration artifacts and possibly the most import – the concept of a ‘plan’; an XML artifact that specifies the atomic installation order of various other OSGi modules, optionally limiting the scope the modules to other modules within the plan. In my view, the ‘plan’ artifact coupled with configuration artifacts provide a clean and dramatically simpler deployment packaging process across environments.

From a Web Application point-of-view, under the hood, it is still Tomcat. Clustering and most configuration is straightforward and is performed in the same manner as you would normally. In fact, your application doesn’t need to be an OSGi bundle, so if you want to migrate slowly to a complete OSGi system over time, Virgo supports this. As a bonus, the latest 3.0.0.M05 Milestone release contains Tomcat 7 meaning the Servlet 3.0 and EL 2 specifications is also now available and the default.

In general, the documentation is pretty good (http://www.eclipse.org/virgo/documentation) and in true Spring fashion there is a decent reference application that takes you through a fairly sophisticated Web Application.

Find out more here: http://www.eclipse.org/virgo/

Community

Possibly the only downside is that I feel Virgo has a reasonably small community when compared to the likes of Glassfish, for example. It is probably explained by the fact that OSGi in the Web is still relatively new, and the fact that Virgo is the successor to Spring DM Server – a gift from SpringSource. I imagine there are many customers still on that platform and the Spring forums still have some value for OSGi issues.

Again, to be fair, whilst the Glassfish community is large I would say only a small percentage are actually using OSGi.

Debugging

Virgo has an excellent, yet relatively undocumented feature. Glyn Normington hints at it, but I don’t think the post does it enough justice. One of the most difficult problems to solve are uses conflicts. Virgo has some nice features around making them clearer in the log files, but sometimes they are a little cryptic. However, Virgo is configured by default to take a snapshot of the current state of bundles during an installation failure. The snapshot alone is of little use on it’s own, however if you navigate to the admin console at http://localhost:8080/admin and choose ‘OSGi state’ there is an option to select live or the dump just created by Virgo – this allows you to see what Virgo sees when it’s trying to resolve your set of bundles. I won’t go into detail here on this, as I’ve dedicated a separate post to debugging in Virgo.

Spring integration

One of the best features of Virgo for Spring developers, is that it came out of Spring DM server and is therefore ‘Spring ready’. That means, it was designed to work with Spring applications – Web applications or otherwise. To get a basic Spring MVC application running in Virgo is not a big deal; it pretty much boils down to creating an appropriate OSGi manifest and modifying the context in web.xml to use the ServerOsgiBundleXmlWebApplicationContext context class instead of the default. From here on, the usual dependency injection and Spring goodness just works and behaves like Tomcat would. The only difference you need to worry about is breaking apart your application into logical chunks (vertically or horizontally, as described in the docs) and deploying them as separate modules to enable hot-deployment.

You don’t really appreciate this, until you try and install a Web Application into another container; such as Felix or Equinox alone. The magic that happens behind the scenes is completely transparent to you.

Why not Glassfish?

In the early investigation stage, it became immediately clear that there were two front-runners when it came to picking a ready-made, OSGi-enabled web server. Glassfish (3.1+) was the obvious competitor as it had a proven track record in the real world of being a fantastic Application Server, and was now OSGi capable (Apache Felix by default). The down side at the time was that it used CDI (JSR-299) heavily internally which conflicted with the Spring Library DI mechanisms. Theoretically it was possible, but it seemed like we were leading down a more difficult path; bending Glassfish and our application in a way that just didn’t feel like the right way to go. I’ll certainly keep my eyes on projects such as the Spring to CDI bridge which help to make these platforms more open.

Learnings

The world is not OSGi ready – be prepared to Wrap Jars

Whilst Spring have provided the somewhat dated Enterprise Bundle Repository – a repository of ready made OSGi artifacts of common libraries – not all libraries you need exist there. In fact, I’m pretty sure some of the latest Spring releases don’t either i.e. Spring Security Core 3.0.5 (It’s not a huge deal though, all Spring bundles now how OSGi manifests created anyway). Not all is lost, however. Both the Maven Bundle Plugin and Bundlor are able to ‘wrap’ existing libraries and turn them into OSGi ready bundles. The catch is ensuring that you use the correct bundle version, package export and package import versions. Pax Construct provides some nice command line tools to get the job done, which uses the Maven Bundle Plugin.

Import-Bundle is evil

OK maybe not evil, but with one exception, and we’ll get to that, my personal belief is that Import-Bundle should be used with caution. I could pretty much say that all uses-conflict issues (see below) that I’ve encountered have been as a result of lazily importing an entire bundle, when only a few packages are actually required. Whether right or wrong, some 3rd party bundles are huge and contain many packages that you’re never going to use. In these cases, importing the entire bundle is like inviting all of Iran and Iraq to a party without telling them – it’s going to end badly. Conversely, inviting a few like-minded Iranians & Iraqi’s will be a pleasant experience.

What I mean by this, is that all of those extra packages not used in the imported bundle still bring along their baggage – transitive dependencies that need to be resolved – the bigger the bundle, the more baggage. This is because Import-Bundle is a shorthand for ‘import all packages in the bundle’. It is an illusion, and at some point, you’ll have several bloated 3rd party JARs that have been poorly packaged with conflicting dependencies all over the shop.

This article would have you believe otherwise, however my view is that Import-Bundle regresses OSGi development to the old-school ‘throw the JAR in WEB-INF/lib’ view of the world. Whilst we get the benefit of re-use, we lose out on precision. True, the tooling to get the job done is still in progress, and configuration files that result in package dependencies are the main cause of this. Bundlor is a great Spring tool that can not only parse byte-code dependencies, but also look in Spring configuration files to determine what needs to be imported.

Declarative Services is your friend

Simply put, don’t do things the hard way – use Spring DM’s or Blueprint’s declarative services model to implement OSGi services and avoid boilerplate code. Take the time to understand how they work, and then never think about it again. Not only will it simplify things, it will make your code more modular and loosely coupled. Think of it as Dependency Injection for OSGi. Read more on Spring DM \ Blueprint here.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:osgi="http://www.springframework.org/schema/osgi"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">

    <osgi:service ref="myExposedObject" interface="com.melbourneit.foo.bar.AwesomeService"/>
    <osgi:reference id="someOtherPotentiallyRemoteObject" interface="com.somebody.something.Useful"/>
</beans>

The above Spring DM XML declaration located by convention in META-INF/spring/*.xml (I used the recommended osgi-context.xml naming scheme) is all that is required to trigger Virgo to expose an object of type com.melbourneit.foo.bar.AwesomeService with name ‘myExposedObject’ which is now available to any other bundle within the OSGi container. Similarly, it will also search for an object of type com.somebody.something.Useful and wait until it can be found. Once found, it is injected as per any other object injected in Spring.

Notice how we don’t care about searching for services, checking for states, runtime exceptions or anything – the DS library takes care of that for us.

Build API and Implementation Bundles

You want to be able to hot swap code at runtime? Then make sure you create API bundles separate from your implementation bundles, and expose the implementation bundle as an OSGi Service (as above). Here’s why:

  • It encourages contract-first development, forcing you to think about the design & features you are implementing up front
  • It will decouple your application from implementation specifics, meaning they are more modular in nature
  • It allows you to create many different providers of that API which, importantly, allows you to hot-swap them at runtime.
  • It (interface first) is a basic principle of Dependency Injection and it will mean many Spring things, like AOP, will work out-of-the-box

So, let’s say for example you decide you want to move from an XML SOAP/RPC based web service to a RESTful one using JSON. For whatever reason, if the WS API objects changed significantly due to the service protocol change your application using it need not worry about it. The implementation bundle can take on that burden to ensure the API interface (contract) is kept consistent. The application simply expresses a dependency on a particular interface which is satisfied at run time by a provider of that interface (service). Turn on this bundle, turn off the old bundle provider and you application should swap over automagically. It need not be as big a change as this, it could be a matter of fine tuning an existing bundle. OSGi and Declarative Services will take care of the wiring for you.

Get to know the console

The Virgo OSGi console contains pretty much all of the information and tools you need to fix bugs, introspect state etc. The Admin application provided with Virgo contains a really nice feature to debug uses-constraints, but apart from that in my opinion the console is much faster and easier to use. Read more about it in my debugging post or at the official documentation.

Bundle-Fragments

We had a need to use Terracotta  for HA session and caching replication, which required a specific Valve customisation to Tomcat’s context.xml configuration file. This is normally really easy – simply add the Valve and put the relevant JAR’s into the shared /lib folder. However, in OSGi this process is not possible. As Tomcat is now an OSGi bundle, it explicitly states the packages that it depends on so dumping a JAR in a directory will do nothing. What you need to do is add the Terracotta packages into the Tomcat classpath when Virgo starts it up.

To achieve this, the most elegant way is to not fiddle with the OSGied Tomcat bundle, nor the boot classpath to make available to all bundles, but to extend it’s classpath using a Bundle-Fragment. Learn more about them on Glyn Normington’s post or at the Spring Documentation.

In practice, you create a bundle for Terracotta (or bundle X) and create a separate bundle consisting only of a manifest file, with the usual headers and a Fragment-Host header specifying the bundle it should latch on to.

Fragment-Host: org.eclipse.gemini.web.tomcat;bundle-version="[2.0.0.,3.0.0)"
Manifest-Version: 1.0
Built-By: Matt Fellows
...
Bundle-Version: 1.0.0
Bundle-ManifestVersion: 2
Bundle-Description: OSGi Web Self-Service Application Reference Implem
entation
Bundle-SymbolicName: com.melbourneit.web.eclipse.virgo.web.tomcat.terr
acotta
Import-Package: ...

You may need to get used to these sorts of solutions, especially if enhancing Virgo internals is required.

Tools for the trade

There are at least 3 tools that I use daily to get the job done

  • Pax Construct – Logically organises your OSGi project into Maven modules, useful tools to wrap 3rd party JARs to make OSGi compliant, sets reasonable defaults, completely transparent if you want it to be.
  • Maven Bundle Plugin – Used by Pax Construct by default, I prefer this tool over bundlor for simple bundles
  • Bundlor – Integrates in Eclipse, STS and Maven and can really simplify your Manifest management. Alternative to Maven Bundle Plugin.

The Virgo Team are awesome

In my experience so far, the Virgo team have been extremely helpful with responding to queries and solving issues and are really working toward building a quality product that meets the needs of their customers. You’ll find the forums quite active and a good resource for troubleshooting, and the guys are all over Twitter so you can keep up with the latest news.

Read

Read the following – you’re parallel dimension self with thank you for it.

You can find all of my OSGi bookmarks here: http://www.delicious.com/mefellows/osgi

Summary

Overall, I’m quite happy with what Virgo provides in the way of support for Spring and OSGi. I’m not 100% convinced at this stage, that OSGi is the fastest means of development – there is most definitely an overhead – however I believe in the long term this is the direction that the industry is moving in, especially with the upcoming Java Modularity requirements for Java 8 I believe OSGi developers will be well prepared for the change.

I don’t believe that Virgo has really pushed the envelope with respect to Hot deployments – one of the main selling points of OSGi. Automating deployments these days is a key activity in Agile project management, indeed it is a best practice full stop. With the current toolset, it is hard to see an elegant solution to automating deployments that allows for hot deployment of modules whilst the Web Application is still running. Plan files significantly reduce the complexity of a deployment, however an artifact within the plan cannot be hot deployed – the entire plan needs to be redeployed. Doing this by hand is possible and Virgo deals with this as expected; if a service dependency is removed at runtime, the application flow requiring it simply pauses until it comes back online. Better still, if the bundle is an implementation provider of an API, you can hot swap out the service at runtime without the Web Application even knowing. However, the cost is that this is a very manual process and that means it’s error-prone.

I’d like to see the features, like the ability to hot-deploy artifacts within a plan or command-line (aka Glassfish asadmin) tools to perform deployments in an atomic and controlled fashion from deployment scripts, for example.

For me, coming up with a best-practice and elegant solution to this problem would really ensure Virgo is the stand-out choice as a Web-enabled OSGi server for the community.

  • Sakae Nakajima

    It is a great article to get the overview of Virgo within 5 minutes. Fantastic job!

  • http://www.linkedin.com/pub/mariano-eloy-fern%C3%A1ndez-osca/25/75a/561 Mariano Eloy Fernandez

    Great post Matthew!

    I’m wandering like Davy Jones searching for an easy way to start with OSGi for web development, but if you google “OSGi web” first search results go back as far as 2008! Right now I agree on the general feeling that it’s quite cumbersome and difficult for an old school programmer to start building OSGi web apps. It’s really hard to set up a little example and move forward to a more “real world” app.

    I posted an issue on https:issues.apache.orgjirabrowseFELIX-2900 to port FELIX desktop examples to web, since I feel there’s still few docs and samples. I think the community should make an effort and write a handful of OSGi web apps of increasing difficulty, some sort of learning track to develop OSGi concepts, sort of how Jeff McAffer evolved the application throughout his book adding complexity one step at a time http:books.google.combooksaboutOSGi_and_Equinox.html?id=RjX8PQAACAAJ.

    So, do you know if there’s some sort of this kind of effort going on? Would you be interested in building up some of this? Hopefully, we won’t have to digg to page 2 or 3 in google results to get excellent OSGi web results like this article!

    Cheers!

    Mariano.

  • http://www.eclipse.org/virgo Glyn Normington

    Great post Matthew! The debugging links seem to be broken and should point to http://www.onegeek.com.au/articles/programming/osgi-debugging-in-eclipse-virgo

    • Matthew Fellows

      Thanks Glyn – link updated.

  • http://www.eclipse.org/virgo Glyn Normington

    Thanks Matt. By the way, after reading your summary I raised an enhancement https://bugs.eclipse.org/bugs/show_bug.cgi?id=369631 for updating individual bundle in a plan.

  • http://www.thingtrack.com Miguel Salinas

    Great article.

    Our company is developing on Spring dm server and Virgo + Spring + Vaadin during more than one year. Developing a product called Konekti a Open Source framework to make module enterprise web RIA apps. The problem that I observe are the Virgo tooling in Helios, they are some weak, and my eclipse suffer may crash. We think that the future of enterprise solutions must be module and OSGi is the best selection.

  • Michael McCarthy

    Really interesting post! We’re in the same boat ourselves actually. Noticed this is a relatively old blog post – are you carrying on happily with your stack or did you move away to something else?

    • Matthew Fellows

      Hi, thanks Michael.

      Yes, we are still using OSGi and Virgo (just in the process of upgrading to 3.6.x) and apart from the general complexities of OSGi, we are very pleased with Virgo – we’ve had it running in Production for about a year now, and have had no issues. It’s very stable in our testing – for example, we went a number of consecutive months without restarting/deploying to it without service degradation. In comparison to competing products such as Glassfish/JBoss, we have found Virgo to be a refreshing breeze…