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.
But 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.
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 andSpring 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.
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.
Share and Enjoy
- Nagarro’s Brigid Wefelnberg finishes 3rd in Kalahari 250 km Ultramaratho…
- Log your exceptions to the cloud
- Windows Server AppFabric
- Nagarro Ranks First in Overall HR Practices in Leading Indian Employer S…
- Windows Phone 7 is NOT the next version of Windows Mobile 6.5
- Nagarro Included Among World’s Top Outsourcing Firms in Two Prestigious …
- Balkrishna Dubey is key speaker at Frankfurt event
- Case study: load balancing high transaction volume databases
- Nagarro Ranked #1 in HR Practices, #6 Overall Best Company in Recent Dat…
- Usability is in the details