OSGi: What modularity can do for you (part 1)
August 27, 2008
It’s been a bit since I blogged last, but I wanted to discuss something I’ve been busy with lately. Inspired by a recent presentation by a friend of mine, Craig Walls, and the announcement by Ales Justin to support OSGi in JBoss 5, I decided to see what all the fuss is about. Perhaps you’ve heard all the hype lately surrounding OSGi, but I wanted to let readers know what they are in for should they decide to trek the OSGi path.
Part 1 will really just be an introduction to OSGi, so for those who have been watching OSGi for awhile now (the OSGi Alliance was founded in 1999!) feel free to jump in on the next entry. But, for those who are OSGi newbies, this will help to get the ball rolling.
So what is modularity all about?
Modularity is the basis of the OSGi world and each bundle is considered a distinct module. Essentially bundles are just standard jars which happen to register with the OSGi container on deployment.
- They inform the OSGi container of what services they expose and what services they consume.
- They run in the same VM and all invocations of the module are in-process calls (no remote invocations).
- Modules are restricted in their interaction with one another as the OSGi container defines restricted class-loading policies (only allowing classes from a module to be exposed if they are explicitly exposed).
Bundles are not a fit for all cases and not all jars are required to be OSGi bundles. In fact using tools like the Apache Felix Maven OSGi Plugin we can choose to selectively embed dependencies directly into our bundles. But, in this case always consider the scope of the classes contained in those embedded dependencies as there are specific rules related to class-loading in the OSGi container.
When modularity counts
Modularity is important in cases where we want to limit what our clients can and cannot use. For example, looking at the Seam Booking Example, let’s say we add a payment service. We can define the payment service through an API, aptly named: PaymentService. There is likely a fairly extensive implementation behind the PaymentService necessary to validate forms of payment, authorize charges, etc, but the Booking application is really only concerned with authorizing payment (not the messy details).
public interface PaymentService {
public boolean authorizePayment(Payment payment);
}
The details of the implementation should be hidden from the Booking application. Unfortunately, if the payment-service.jar is loaded into our classpath, we suddenly have access to not only the interface, but all the implementation classes as well. So there is nothing to stop developer A from directly instantiating and invoking PaymentServiceImpl. And when developer B changes the name of this class and its implementation months down the line suddenly we have a break.
OSGi solves this by only providing visibility to the services which are exposed by a bundle. This makes things simple in the following package structure:
payment-service
- src/main/java
- com.solutionsfit.payment
PaymentService
- com.solutionsfit.payment.internal
PaymentServiceImpl
... ...
Notice the package structure above. The PaymentService interface is separated from the implementation which is in general good practice, but externalizing one package or the other has never been enforced. So how can it be done with OSGi?
Remember that crazy MANIFEST.MF file that perhaps you looked at one time to see what was in there. Or maybe you just noticed it sitting there and never bothered to look at it (Maven generates it for us anyway right!?). OSGi introduces some specific entries into the MANIFEST file that defines exactly what packages are imported and exported. So for our example above our manifest may look something like:
Manifest-Version: 1.0 Bundle-SymbolicName: com.solutionsfit.payment-service Bundle-Name: Payment Service Bundle-Version: 1.0.0 Bundle-Description: Payment Service Import-Package: org.apache.commons.lang Export-Package: com.solutionsfit.payment Build-Jdk: 1.5.0_15 Bundle-ManifestVersion: 2
These entries simply let the container know what they require from other modules to execute:
Import-Package: org.apache.commons.lang
And what they make available to other modules:
Export-Package: com.solutionsfit.payment
Notice that we haven’t specified anything earth-shattering here. All we’ve done is said that we require commons-lang to be provided to us and we are making the com.solutionsfit.payment package available to others. Note that I don’t state where the dependencies come from! This means that in the above case any registered bundle could export the package that I use. You can also specify a version to be more specific:
Import-Package: org.apache.commons.lang;version=”2.4.0″
This allows multiple bundles to export the same package but we only use the version we are interested in. This becomes very useful in addressing dependency version issues between jars. Here bundle A can depend on 2.3.1 while bundle B depends on 2.4.0 and the OSGi container enforces this restriction for us. In the example above by not specifying a version, the latest version registered by a bundle will be chosen.

Note in our diagram above that the PaymentService is the only class available to the org.jboss.seam.example.booking bundle. This is because we explicitly specified that its package should be exported meaning that the OSGi container makes it visible to other bundles.
This all looks very Maven-ish to me…
Your right! The naming conventions and versioning are very similar to Maven and they fit well together. In general, the BundleSymbolic-Name is determined by appending the group-id and artifact-id of your Maven POM. The version is just stripped directly from the POM, so it all fits. In fact, if you want to make your jar a bundle, simply create a /src/resources/META-INF/MANIFEST.MF file by swapping in your project details in the entry above and add the following lines to your POM:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>
src/main/resources/META-INF/MANIFEST.MF
</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>
</build>
The next packaging of your project will be a OSGi bundle. Of course, the Apache Felix plugin mentioned previously provides a much more automated approach, but if you are into manual entry (sometimes the best way to learn), this approach will certainly work.
So besides visibility, what does this buy me?
Imagine the Booking application is running in production and your customers are happily booking trips to their favorite vacation destinations. You have realized that there is a critical bug in the production payment service that could result in substantial losses for your company. Do you bring down the application for temporary maintenance and perhaps lose those customers? No way!
With OSGi there is very loose coupling between the bundles. While OSGi will simply provide back a direct reference to the object registered by the bundle, this allows helpers like Spring-DM to proxy the PaymentService that will force the org.jboss.seam.example.booking to wait should the service go down.
If we simply replace the bundle with a bundle that includes the fix, the container will unregister the old bundle and register the new bundle. The proxy can then handle the reference shuffling and resume the service invocation. This interaction will be almost instantaneous. Your customers will be completely oblivious to what has happened and you just saved your company a substantial amount of money (do I hear bonus?).

The diagram above obviously omits quite a bit of the magic of OSGi and hides some implementation details, but demonstrates the general idea.
Alright, alright, so all this stuff is very basic, where are the integration points! Don’t worry, in upcoming posts I’ll further discuss how the Booking application can use OSGi to simplify development.
Stay tuned…
Posted in 


content rss
August 28th, 2008 at 3:10 am
Very nice introduction! Just one thing, service are NOT proxied by the framework. You directly use the object registered by the other bundle. To support the dynamism, the user of the code must clean up when the service disappears. Though this sounds like a tad of unwanted work, there are many helpers like ServiceTracker, iPOJO, Spring-DM, Declarative Services, etc. that makes handling these dependencies trivial. Several of these helper systems use proxies.
We tried to keep the spec as minimal as possible guaranteeing interoperability, allowing others to provide competing products to make it easier because this is so often in the eye of the beholder.
Thanks for the article! Kind regards,
Peter Kriens
August 28th, 2008 at 7:15 am
Good to hear from you Peter! Thanks for the clarification here. I have updated the posting to reflect this point. I have been using Spring DM for OSGi wiring up to this point but I will certainly take a look into the other options you suggested as well. Please let me know if you have any further comments, they are much appreciated.
August 28th, 2008 at 8:25 am
That’s great and all but can I use Seam to generate my stateful entities?
Good job on the OSGi intro.
September 1st, 2008 at 7:54 pm
Jacob, does OSGI provide any support for modules with web resources? For example, can I drop in a new module and have new pages added to my web application? I would think this means that new classes are being added to the classpath as well as new resources, such as jsp, images, javascripts, and stylesheets would need to be added to the application’s web root. Is there any support for this by any OSGI container or tool?
Nice graphics. Appropriate, subtle, and attractive.
September 3rd, 2008 at 7:59 am
Yes, war projects can be modules, but to get them working with the servlet container takes a bit of work (due to class-loading constraints). Spring DM 1.1 supports this, see Chapter 8. Web Support.
From what I’m aware of, there isn’t support for this at the moment (really outside of the scope of a standard war deployment), although I certainly think what you are looking for would be quite useful. In fact I have a client that would love to have this
Not sure how you would achieve this off hand with a standard war deployment. Did you have any ideas?
You could always ping the forums for Spring DM and find out if there are plans for support of something similar.
September 3rd, 2008 at 11:24 am
An example of use case for these web resources might be something like an Administration tool where you want to be able to add new administration areas, to include new web pages, images, behaviors, and styles by adding new modules to the application.
Thanks Jacob, I am going to check out Spring DM. Chris recommended that to me as well.
November 7th, 2008 at 2:43 am
An alternative approach to bridging the web world and the OSGi world is to use the servlet bridge (here http://www.eclipse.org/equinox/server/http_in_container.php) to embed an instance of OSGi into your web application.
As OSGi includes a servlet container you can include static resources (HTML, js, etc), servlets, and with a bit of additional work JSPs, in your bundles just fine. There are extension points that allows you to register you web resources with the OSGi world. The outer “servlet bridge” web app contains a servlet that bridges the web appication and the OSGi instance; i.e. it forwards incoming requests to the OSGi instance.
Yes, this does mean that your standard unit of deployment is now the bundle (in the true sense of the meaning) not the .war. Some see this as a disadvantage. Others, including me, who understand that eventually bundles will be a standard unit of deployment into all traditional application servers see this as an advantage in that you can start getting your developers used to bundles now. The servlet bridge can be incorprated into your web apps and you can carefully move more and more elements of your web app into the bundles.
December 12th, 2008 at 9:04 am
[...] The Future of the Internet according to Jonathan Zittrain Saved by bizuri on Fri 21-11-2008 OSGi: What modularity can do for you (part 1) Saved by The3Heads on Fri 21-11-2008 BadA head structure Saved by ThereseTragedy on Tue [...]
September 15th, 2009 at 10:01 am
We are currently working on the jboss negotiation and seam application security configuration to allow user auto login to application. We run into some issues. In your comments in the following blog, you mention about have it work for you. I wonder if you have any blog talking about this.
http://www.coderanch.com/t/439299/JBoss/JBoss-Seam-Single-Sign
Thanks a lot.
Louie
December 1st, 2010 at 7:52 pm
Very nice article!
>>this allows helpers like Spring-DM to proxy the PaymentService that will force the >>org.jboss.seam.example.booking to wait should the service go down.
is this proxy feature specific to Spring DM or part of the spec? In the picture you showed that authorizePayment() method is put on hold until the service comes back. What if the service goes down while control is in the authorizePayment() method?
Is it safe to deploy bundle updates in production servers w/o removing them from taking live traffic?