OSGI, wish I had it before | from an architect’s mind

This is one of my old blogs – that i had published on an internal site, re-sharing it here.

Very recently i worked on a project and the architecture (from highlevel) had following components (among many other):

1. Module builds and Dependency management, we had tried to relate the pieces of functionality into one and termed them meaningful modules e.g. A is a module which owns a meaningful business set of functionality, B is another module, which owns another set of meaningful functionality (meaningful business entity), so forth and so on. With in each module we had tried to keep UI and Service layers separate. Also, things which were larger and couldn’t fit in module boundaries or were non functional in nature had all been assigned to CORE module (s). There were also UI components, which were not specific to any module, say menu (header et al) and were bundled in to CORE-UI as a module.

The idea was to have dependencies exposed through API bundles e.g. A-api-1.0-snapshot.jar will contain all the exposed service contracts, and a B module could depend on any class/interface from this bundle. However, A-impl-* couldn’ t be a dependency for B module as it was supposed to contain implementations (concrete internal implementations – including exposed contract impls).

Dependency management as a philosophy was implemented as part of overall “deployable unit” (inter module) and also internal to each of these modules (intra module). E.g. A could depend on B and C, but C and B couldn’t depend on A.

we wanted unidirectional dependencies in system. Besides, with in each module UI could depend on Service and this dependency is also strictly unidirectional. E.g. a Action bean could depend on Service but a service MUST NOT depend on AB.

2. Versions and version management, versioning for us was part of the bigger framework and hence we wanted to have this in place for each our modules. All the modules were marked with a version which is independent of any other module’s versioning.

My original idea was to have 3 digit versioning, say 1.0.0, where in first digit is your build number, second digit is the incremental build and third digit should either be a snapshot build or a build which was part of the release. So, If I could set up the scheduled builds (CI) the build should be core-impl-1.0.snaphost.jar. We could version this module build to be 1.0.3 if we release this out.

Digit 1 – Build no.
Digit 2 – Major build no.
Digit 3 – Incremental build or snapshot build or patch build. I don’t think we need any more digits in there.

3. Builds and change control, build artifact in our case was an enterprise archive file. EAR is a composite bundle of module builds (jars) with a web application definition with all JSPs and site resources (required) bundled in WAR inside EAR. I wanted us to be able to version the EAR build different from module builds, which is how the system was designed. However from change control perspective our builds were still dependent on branching of code base, which is a tedious process. I wanted to be able to specify a specific version to be bundled in an EAR for a given module and avoid all “manual” work of creating the patches. I wanted us to be able to control the code base using versions and avoid using branches etc. e.g. I wanted A bundle to be frozen for a given period and wanted to release other modules in a build. I should be able to set the build scripts in EAR to be able to pick – A-impl-<myspecifiedversion>.jar vs picking the latest snapshot version of jar. This would mean we wouldn’t have to do anything manual and could control the build dynamically for a release.

There are obvious advantages with what I wanted to achieve: – extensibility
– maintainability
– testability

by

– Decoupling of layers
– Decoupling of modules – easier code management

so forth and so on, and it did fit with our overall architecrual philosphy of using “Service Oriented Approach” really well. All the folks familiar with Sping based development would easily identify with “Service oriented” approach in form of bundles.

This was okay till I could roll it out as a document, however we needed to also enforce this using
a “automated” mechanism. No price for guessing we decided to do this in “build” scripts. I used ANT + IVY against MAVEN (that story for another day).

So, we could define the dependency at granular level and could also control the direction of dependency and hence could control the “kind of coupling” we would allow.

I always thought, it was okay to control the dependency at static level, but what if i could check the same dynamically and control it as part of bundle metadata. That would have given me flexibility to actually pick and choose the “contracts” i would like to expose at package level vs. JAR level. That would also let me define dependency at version level and would still let me run an old version of my JAR in same VM. There were many thoughts and ideas … and i had no time to look around to find a “dynamic” yet easy and powerful solution.

OSGI – comes to the rescue for all of us who would like to pursue such a philosophy for our projects. It is pretty mature, has got many versions of implementation in different open source projects (including one in Spring). It practically liberates you from:
– JAR hell

– Classpath hell

– and dependency hell 🙂

e.g. in my case, I could remove all of API and IMPL concept and control all the dependencies at package level by specifying simple configuration settings in JAR manifest files and make the dependency control work for me.

Consider a longer running project, where in a dependency “commons package” will change generations, you would like to take advantage of new features but can’t as there is a lot of old code (call it legacy), which still depends on an old package or a class or a method, which is no longer supported, well now you can do that using OSGI, you can keep both the versions of commons package and work in same VM.

There are many more advantages – which are better read over OSGI initiatives. Go have a read and liberate yourself and your project from the mess of managing dependency 🙂

To add to this, Java (VM) is going to introduce the concept of “Super packages” as part of Java 5 and that is going to be another big big change to language itself post Java 7. The concept is largely same as that of OSGI, just that it will have syntactical support right out of Java and dependencies would not need be specified as part of manifestation files. Besides, i think you might need to deal with another archive

(MAR) :P.
Proposed code may look like:
@version(1.0.0)
@ExportResources{(abc.jpg, icon.gif, script.js;} @ModuleAttributes{?,?} @ImportPolicy{ImportPolicyImplementation.class} super package com.sun.myModule {
export com.sun.myModule.myStuff.*;
export com.sun.myModule.yourStuff.Interface; com.sun.myModule.myStuff; com.sun.myModule.yourStuff; com.sun.SomeOtherModule.theirStuff;
import org.someOpenSource.someCoolStuff;
}
go have a read on following:
̈Static module system – JSR 277
̈Dynamic module system (OSGI) – JSR 291
̈VM and Language support – JSR 294

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: