SOA in a JVM

November 26th, 2007 | by Bill Kayser |

There has never really much debate about whether Service Oriented Architecture is a good idea or not. Based on principles such as loose coupling, encapsulation, location transparency, and the separation of infrastructure and applications, it has always had broad appeal. IT executives like the uniformity of a standards based solution that provides management and visibility across all applications. Application Owners like that it gives them much needed interoperability with other parts of the business. And developers especially like the layered architecture and loose coupling achieved with relatively simple plumbing, unlike the component model predecessors of earlier years.

Simple PlumbingBut this appeal isn’t limited to distributed enterprise applications. Wouldn’t software developers like to see a Service Oriented Architecture for the “services” located within a single JVM?

Java Enterprise Software is never written from scratch. Typically it involves writing components that utilize 3rd party libraries, extensions to application frameworks, communications with different tiers. Just look at the class path of any Java Enterprise Application and you’ll see a long list of jar files including JDBC drivers, web application frameworks, validation libraries, Jakarta Commons libraries, and various client libraries. Also, typically you’ll see a number of entries developed by other groups in house: proprietary frameworks, common core utilities, i18n libraries, validation frameworks–on and on.

The end result of the typical class path of a Java application is a giant set of classes from many different libraries all thrown together into a big soup where any class technically can access any other public class, directly or indirectly. Furthermore, nothing guarantees that all the necessary parts are present. Just because everything compiles into jar files doesn’t mean the classes referenced at runtime are actually going to be there, or for that matter be the correct version.Poor Plumbing

In these applications, dependencies are hard to manage. Tools such as JDepend can be used to identify fragile APIs, problematic dependencies and tight coupling, but nothing really prevents developers from using classes they shouldn’t be using. For instance, once someone uses an Oracle specific class in the Oracle JDBC driver they will be unable to use a different vendor’s driver. Or some code might inadvertently reference an implementation class that is not part of the public API and break on a subsequent upgrade of the library.

Now imagine that the different libraries and frameworks were actually services. They had a public API which is accessible to other components and private implementation classes which are not. The dependencies of any service would be explicit, listing the other services and versions which are required at runtime for them to operate properly. These constraints would be enforced at compilation time as well as at runtime; if a required service in a particular version range is not available in either instance, the system fails fast with an indication of what’s missing. If a service tries to access a public class in a service not listed as a dependency, a class not found error occurs (an error also caught at compilation time). These libraries would still materialize as jar files, but these jar files would be service modules which can be moved in or out of an application even while the application is running. There would be no separate step of composing the classes of a jar file with globs in an ant file. The definition of a service implies the contents of the jar files–no need to maintain an ant file, just a manifest file for the service identifying it’s version and dependencies.

Some of this may already sound familiar. Inversion of Control (IoC) frameworks such as PicoContainer and Spring provide some aspects of the separation of implementation and interface already. Application servers use class loader hierarchies to enforce separation of class visibility within a single JVM. And various application architectural patterns such as Abstract Factories and Dependency Injection provide a means for protecting implementation classes and avoiding fragile APIs.

While these frameworks are all helpful they still leave the programmer in charge of introducing and utilizing them. In most cases, the JVM still loads classes from the big vat of class soup indicated by the class path. What is needed is something more fundamental, something that would completely “invert” the control of the whole application, executing everything as services, not the chosen few components. Instead of the JVM invoking main() on your main class with a single class loader for all your classes, a small application runtime is invoked that looks at all your services, wires up all the dependencies between the services, blocks any that have unresolved dependencies, then invokes start() on each of the services.

Hold it right there, you are probably saying. It already sounds complicated. You might be picturing some big API, or massive documentation you have to go out and read. Sign up for the classes, read the articles, copy the example code, and a week later you’ve got HelloWorld done. Stick with me and you’ll find out it’s not like that. The runtime I’m speaking about is called OSGi and while it is complicated in what it does and how it works, it’s remarkably simple to utilize with the right tool. And more likely than not, you are using that tool already.

OSGi is a standard for a Java component model that has several open source implementations. The most common implementation is calld Equinox. Equinox is the runtime used by the Eclipse IDE and all Eclipse RCP based applications. It’s the lowest level on the Eclipse application runtime stack. It provides the SOA architecture on which Eclipse runs, as of version 3.0. If you’ve programmed RCP applications you’re already familiar with Equinox, but even if you’re just an Eclipse user, you might have noticed that Eclipse is composed of plug-ins which all live in the plugins directory in the Eclipse installation. These plugins are generally jar files or directories that represent the various components of the application. There can be hundreds of these. As an Eclipse user, you may appreciate that you can extend Eclipse with new features by simply adding new plugin jars to the plugins directory and restarting the IDE. If you’ve looked at how Eclipse starts, you’ll see it simply invokes a small jar file on the command line–no reference to any application libraries or classes. As a plugin developer, you are more keenly aware of how these plugins are built, their lifecycle, and the actual mechanics of extending the IDE.

What you may not be aware of is that the plumbing for all of this is not part of the IDE, or even part of RCP, but is actually part of the Equinox runtime bundled with Eclipse. The main class invoked when you start up Eclipse is actually an Equinox entry point, and none of the Equinox code knows anything about Eclipse, RCP, SWT or any of that. This is very important because it means that Equinox can be used as the runtime for any application, including Swing and Web applications.

Eclipse OSGi Architecture

Eclipse/RCP Architecture built on OSGi

What does all of this mean for you? You have the means and the opportunity to be building your applications with a service oriented architecture, much more easily than you might expect, and I’ve only scratched the surface of the benefits.

You may have noticed it’s been a pretty long gap between my last entry and this one. I’m currently on a leave of absence while managing a new dependency in my family, in the form of a baby boy born on November 14. I’ll pick up this thread in a week or two and show you how we converted our 600,000 line multi-tier swing based application into a service oriented architecture, replacing over 30,000 lines of ant code with about 200 lines, and vastly improving its maintainability and longevity in the process.

6 Responses to “SOA in a JVM”

  1. By Abhijat on Dec 3, 2007

    Interesting, as usual, Bill. I like Apache Felix because it started as a clean separate project and the community does not center around an IDE.

    Have you tried moving a (complex, real world) component bundle between the two implementations - Felix and Equinox?

    There is an interesting article - “Android and OSGi” on the OSGi blogs at http://www.osgi.org/blog/2007/11/android-and-osgi.html .

    Now time for me to get back to moving my ancient component framework to Felix :) .

    –Abhijat

  2. By Bill Kayser on Dec 5, 2007

    I haven’t done anything with Felix but we are using Knopflerfish’s OSGi runtime as well as Equinox. Bundles packaged according to the OSGi R4 spec shouldn’t have any issues moving between runtimes. Unlike J2EE, the API is small and tight, particularly if you are just utilizing the component/lifecycle part, and not relying too much on the services part. Libraries packaged up as bundles using something like bnd should have no issues on different runtimes.

  3. By Abhijat on Dec 9, 2007

    Saw it yesterday (Friday, 7th of Dec.):

    “OSGi Alliance Adds Free Supporter Participation Class” .

    For more details either visit the osgi page or download the PDF document explaining this (new participation class) from http://osgi.org/news_events/documents/SupportClassFINAL11.29%5B1%5D.pdf

  4. By Peter Kriens on Jan 22, 2008

    > … and not relying too much on the services part.
    The services part is where you actually gain most in the decoupling … :-)

    Nice article! Kind regards,

    Peter Kriens

  5. By CalArch on Feb 13, 2008

    Love the blog, if i may ask, what software are you using? how much does it cost? where do you get it? If it’s not a secret email me some details wouldya?

    thanks in advance!

  1. 1 Trackback(s)

  2. Jan 26, 2008: links for 2008-01-26

Post a Comment