There’s been a lot of hype around OSGi over the last year or two in the enterprise space. Last year even Caucho dallied with adding OSGi support to Resin, though we’ve abandoned the idea in the meantime. In this post, I’ll tell you what’s cool about OSGi, why we were initially attracted to it, why we eventually dropped it, and what we did instead. The more I talk to enterprise developers who’ve actually used OSGi, the more I hear this same story.
Update: Rob Harrop informed me that there is an emerging specification called RFC-66 for enterprise web/OSGi integration.
Even though OSGi is relatively new to enterprise developers, it has a long and storied history in the mobile community. The service model promoted by Peter Kriens is also really neat and allows you to add new services to a JVM at runtime. If you’re developing a mobile application, being able to add and remove services without restarting is essential. A service could be something like a mobile application or a communication stack for WiFi or 3G when a network comes into range. So services are a really cool feature of OSGi.
Most of the attention that OSGi has been getting from the enterprise developers is related to its modularity features. The core functionality that OSGi provides is a Bundle-based framework in which .jar files have explicitly defined visibility rules. What this means is that you can bundle a group of packages into a .jar, define which packages the .jar provides, which packages it depends upon, throw all your .jars into the OSGi container, and have it sort out the visibility for you. One of the cool features of the dependency resolution is that you can also have multiple versions of the same package/bundle floating around and OSGi can isolate these versions, protecting you from conflicts. This approach to modularity is another awesome feature for mobile because you may need to upgrade components at runtime, but not all the dependent components may be compatible with the upgrade.
Caucho’s journey with OSGi
Based on the demand and some interesting tutorials, we decided to implement OSGi in Resin last year. One of the things we liked is the dependency resolution, but we couldn’t quite figure out how OSGi bundles and services should fit into a web or enterprise world. There are a couple of ideas that are floating around about what’s the right thing to do in this case. One approach is to run your application server as a bundle with the OSGi container controlling the JVM. We rejected this approach, at least for our initial draft, because Resin already has sophisticated startup mechanisms in place which didn’t quite work with that model. The other approach is to run an OSGi container within the application server, which worked better for us. Scott wrote the code necessary to wire together the dependencies, which involved a few crazy classloader tricks, and we were happy with the functionality.
So the next question was, “How do you actually write a web application in OSGi?” Specifically, how do you write a frontend? If you only write business components in OSGi, how do they communicate with the frontend? There’s no lack of ideas about what can be done to solve these problems - draft proposals and independent implementations abound - but there’s no emerging standard that really makes this clear. With this confusion, we set OSGi on the backburner for a while until a standard or even de facto standard became real.
In the meantime, I set to work on our Eclipse plugin and got to work with OSGi first hand. The experience was painful. With hundreds of bundles in the runtime and an obscene number of versions for many of them, the first impression was one of complexity. Once I actually started looking inside of the Eclipse bundles, I realized that they had also added Eclipse-specific metadata. This says to me that OSGi’s model isn’t quite adequate to handle what Eclipse is trying to express. More over, the division of packages within single features seemed arbitrary and overly confusing. Specifically, I was working with the WebTools project framework for the Resin plugin and was confronted with a set of bundles for each subproject. There were separate “core” and “ui” bundles for each subproject, which is logical, but all sorts of crazy tricks were played to import non-exported packages between the two, and between subprojects. That’s a bad sign.
None-the-less, I can understand why Eclipse would choose OSGi - it is a large, complex product with many possible conflicting modules due to its open-source nature. As a side benefit, you’d like to be able to add services at runtime - such as new plugins and features - without having to restart because Eclipse is a bit of a beast. (Of course Eclipse warns you that it would be better if you do restart after adding any new plugins, so it’s questionable if that actually works in practice.)
Moving away from OSGi
After this brief foray into OSGi land, we started evaluating what value OSGi added to the enterprise world. Are many enterprise web apps complicated in the same way that Eclipse is? Specifically, do many real enterprises add tons of experimental plugins and features to their sites that need isolation to make them work together? Hopefully not. Are there significant overlaps in requirements with mobile apps? Specifically, do enterprise applications need to add services at runtime without restarting the JVM? Maybe - it would be a nice feature to have, but if you’re running a large enterprise site, you’d probably prefer to get a clean boot of a system with the new service, test it, then start directing traffic to the server. No matter how clean the framework, administrators will always prefer a freshly booted machine.
How about the component model? Does it improve development? Eclipse showed me how the bundle system encourages over-componentization, but was this problem present for enterprise apps? I saw a talk by Rob Harrop of SpringSource (PDF) at TSSJS in Las Vegas in which he talked about using Spring’s DM server and the discoveries they made while creating a web framework around OSGi. It was a interesting talk and Rob was definitely excited about OSGi and finding best practices. In fact he seemed to make all the same observations that I did - easy temptation to create too many bundles and the need to shift boundaries throughout the development cycle - but came to the conclusion that these were worth solving because of the dependency resolution.
Well, we certainly agree that the dependency resolution features of OSGi are cool, especially given that a lot of projects use many libraries with second-level dependency conflicts. But do you need the complexity of OSGi for that? Moreover, are you ready to switch your entire programming and component structure of existing applications to OSGi? We thought that these are pretty big hurdles, so we decided to morph our OSGi classloader backend into Pomegranate. The idea is simple: start with the dependency metadata many people already have in the form of Maven pom.xml files, then do the same resolution magic on Maven jars instead of OSGi bundles. Pomegranate even handles multiple versions of the same library. That functionality probably solves many of the problems that enterprise developers look at OSGi for, without making you learn a whole new tool set and metadata formats. Certainly Pomegranate doesn’t aim to be a complete replacement for OSGi, but rather a focused approach to solving the real problem of dependency resolution without changing the entire programming model.
Scott wrote a quick overview of Pomegranate and we’ll soon have real docs for it, but I wanted to give the story of how we got to Pomegranate first. What’s your experience with OSGi? Has it helped your development/deployment or just made it more complicated?