In the first installment, I outlined a simple web application. In this post, I will be turning that application into two parts – an OSGi bundle, with a client web app.
But before we get into that, let’s go over setting up the environment.
Installing Glassfish v3
The first step is to get Glassfish v3 and install it. Unfortunately, the OSGi features are still on the bleeding edge, so you can’t even get buy with the “prelude” release – I used a recent “promoted” build from the start of September. The Glassfish Promoted Builds page has the full list – there’s a handy “latest” section at the bottom. I use the ‘latest-glassfish-unix.sh’ script, but there’s a Windows build if your perversions take you that way…
Once you’ve downloaded, simply run the script or EXE file. This should launch a GUI that will prompt you through the installation process. Take note of where you install it to, though – I’ll be referring to that as $GF3
in my examples.
If you like, feel free to test your installation by installing the simple application. This can be done via the command line as:
# in the status_app directory
mvn clean package
# start the domain - domain1 - if it's not already started.
$GF3/bin/asadmin start-domain
$GF3/bin/asadmin deploy --contextroot /statusApp target/status_app.war
You should now be able to go to http://localhost:8080/statusApp/index.html and test the app.
An OSGi Primer
OSGi technology is the dynamic module system for Java™.
What exactly is OSGi, anyway? I’m not an expert, so my definition won’t be quite right, but here’s the way I’ve been looking at it: OSGi is a classpath manager on steroids, and an attempt to get out of classpath hell. Basically, an OSGi container is a container for bundles. Bundles specify what Java packages they export, and can specify what packages (or other bundles) they need. And the container takes care of the wiring.
No nasty “class not found” errors because you’re missing a JAR – you get told of them at deploy time. No complicated class loader issues which mean two classes aren’t equal – the OSGi container gives your classes to you in one class loader. No possibility of getting errors about Log4J being configured because it’s accidentally on your classpath: your classpath consists of only what you say you want in your bundle.

So what is an OSGi bundle? Well, the simplest example of an OSGi bundle is a standard Java JAR file – with a few extra entries in the MANIFEST.MF file. The manifest file is used to configure the OSGi bundle – to let it know what packages or bundles to import, which packages to export, and so forth. A full list of the standard manifest headers can be found in Chapter 3 of the OSGi Core Specification.
Overview of the sample application
The sample application consists of 8 files at this stage:
- status_app/pom.xml
- The Maven POM file
- status_app/src/main/java/net/twasink/osgispike/bean/Counter.java
- Very simple counter; keeps the count in a static variable. This is just a POJO with no external dependencies
- status_app/src/main/java/net/twasink/osgispike/web/IncrementServlet.java
- Servlet mounted on /Increment. Causes the counter to increase.
- status_app/src/main/java/net/twasink/osgispike/web/StatusServlet.java
- Servlet mounted on /Status. Causes the counter to increase.
- status_app/src/main/resources/net/twasink/osgispike/web/increment.html
- Template for the increment servlet.
- status_app/src/main/resources/net/twasink/osgispike/web/status.html
- Template for the status servlet.
- status_app/src/main/webapp/index.html
- Simple "welcome" page for the application
- status_app/src/main/webapp/WEB-INF/web.xml
- Configuration file for the web app
Creating the bundle
Okay, that’s the background information out of the way. The task now is to get the Counter out of the web app and into a new bundle. The first part was simple enough: I just created a new empty project and moved the counter there, resulting in a structure like this:
- counter_bundle/pom.xml
- The Maven POM file.
- counter_bundle/src/main/java/net/twasink/osgispike/bean/Counter.java
- Very simple counter; keeps the count in a static variable. This is just a POJO with no external dependencies

In order to keep the webapp compiling, I had to go back and add a dependency to the new counter_bundle
module. Because I want to use OSGi to manage the classpath, I put this dependence at the provided
scope.
If you’ve been playing along, then we now have two modules – the counter_bundle
JAR and the status_app
WAR. We need to turn the counter_bundle into an OSGi bundle and then deploy it. To do this, we need to add the following to the MANIFEST.MF file:
Bundle-Version: 1.0-SNAPSHOT
Export-Package: net.twasink.osgispike.bean
Because I’m using Maven to do the builds, I did this by tweaking the maven-jar-plugin
configuration – you can see that in the sample files later.
Now I’m ready to build and deploy the bundle. There are a few ways to do this, but the one that worked for me was to copy the JAR file into the autodeploy-bundles
directory in the glassfish domain.
# in the counter_bundle directory
mvn clean install
cp target/counter_bundle.jar $GF3/glassfish/domains/domain1/autodeploy-bundles/
If you’re monitoring the Glassfish logs, you’ll should see a reference to ‘Started bundle: ‘ appear within a few seconds.
We can now rebuild and redeploy the status app, and we will be using the new bundle. This works because Glassfish puts OSGi bundles into the app server classpath.
# in the status_app directory
mvn clean package
$GF3/bin/asadmin deploy --force=true --contextroot /statusApp target/status_app.war
Try hitting the index page, and you should see it’s all working.
Wrapping up.
That’s all that’s involved in creating an OSGi bundle – at least a very simple one. They can become more complicated, as we’ll see in subsequent posts, but the mechanics don’t change very much.
As with all posts in this series, I have the source code available; it’s available under either the Creative Commons license (as per the blog) or under the aptly-named WTFPL. It’s not very much code.
The bundle we have built is still a little basic. The counter is still using a static variable to store its data, and new instances are being created by the servlets at will. In the next instalment, we shall convert this simple bundle into a (still simple OSGi Service – this will allow the counter to become a POJO without the static.
I apologise to anyone who finds the font-resizing a little odd; I had to rebuild my blog theme last night due to a stuff-up on my part, and I haven’t got the sizes right yet.
One gotcha for anyone experimenting – the webapp will obtain a reference to the Counter at servlet init time – probably when you first hit the pages. If you re-deploy the Counter bundle, this change is NOT picked up until you restart or redeploy the web app. This isn’t a bug, as such – more a side effect of the naive approach being used here.
This particular style of deployment is probably best for utility libraries, like Spring or HIbernate, or other technology frameworks.
I will cover ways to pick up changes to bundles being used later.
I have no idea of Glassfish resolves version conflicts on the in the application server’s classpath – so don’t ask. 🙂
GlassFish does not resolve any version conflicts in this case; it makes available all exported packages to all Java EE applications. If you want explicit control over dependencies, you can deploy your web application as an OSGi bundle. I call this a hybrid application. Take a look at http://weblogs.java.net/blog/2009/06/14/developing-hybrid-osgi-java-ee-applications-glassfish
Thanks, Sahoo. That’s basically what I thought, but I didn’t want to commit to that.
I will be covering hybrid applications in a few entries – I’ve been spending a lot of time reading your blog recently, and would highly recommend it to others.