The Two Faces of Modularity & OSGi
There are two aspects to OSGi - the OSGi runtime model and the OSGi development model. Today, emphasis is on the runtime model. But eventually, the importance of the development model will take center stage.
The Runtime Model
The runtime model includes support for the dynamic deployment of bundles, different versions of bundles, dependency resolution, enforcement of module boundaries, and the overall dynamism of the runtime environment. The runtime model is relatively mature, and many vendors are leveraging OSGi to take advantage of the runtime capabilities resulting from increased modularity. To an extent, this allows the enterprise to realize the advantages of OSGi without knowing much about it. Faster application startup times and platform adaptability are two advantages organizations will realize as vendors bake OSGi into their products.
While there is some dispute over whether vendors will expose the virtues of OSGi to the enterprise, eventually they will (SpringSource dm Server currently does). They will because the enterprise stands to gain considerably from a more modular architecture. There is benefit in a world void of classpath hell and monolithic applications. There is benefit in modularity, and eventually the enterprise will ask for OSGi. In the end, the enterprise will get what they’re asking for, and when they do, the development model will become very relevant.
The Development Model
The development model has two facets - the programming model and the design paradigm - surrounding how organizations will use OSGi to build more modular applications. The programming model challenge is already being addressed with technologies such as Spring DM, iPojo, and OSGi Declarative Services, where developers are able to tap into the capabilities of OSGi without worrying about the OSGi programming model. These frameworks help encapsulate dependencies on the OSGi API so your code doesn’t have to talk directly to the API. The separation of concerns achieved through these frameworks ensures Java classes remain POJOs that aren’t dependent on the OSGi framework. This makes programming and testing much easier.
But the design paradigm must also be addressed. How does an organization create a more modular architecture? What is the right granularity for a module? How heavily dependent should modules be on each other? How do we minimize module dependencies? How do we break apart larger modules into a smaller set of more cohesive modules? When do we do this? These, among others, are the important architectural and design questions that surround OSGi in the enterprise. Let’s take two different examples of technologies that prove the pending relevance of the OSGi development model - object-oriented (OO) programming and EJB.
In the early 1990’s, OO was touted as the savior. Development teams would be able to build systems by composing reusable objects. This promised significantly reduced time-to-market and higher quality software (we’ve never heard that before, or since, have we?). It was never realized. There were a few reasons for this. Objects are too granular to serve as the foundation of reuse. Developments teams also had difficulty grasping and applying OO concepts correctly. Deep inheritance hierarchies laden with base classes rich in functionality contributed to poorly designed systems. In general, OO was an early failure.
The runtime capabilities of OO languages provided features such as polymorphism and dynamic binding, and developers were able to easily understand many aspects of the programming model. Using dot notation to invoke methods and defining private member variables were trivial concepts. But it took a long time for us to understand how to design good programs using OO. What we accept today as simple truths surrounding OO design (”favor object composition over object inheritance” and “program to an interface, not an implementation”) were unknown, or at least a mystery to us, 15 years ago.
Enterprise Java Beans (EJB), and especially entity beans, were presented as part of Java EE as a way to componentize business applications. The runtime capabilities of EJB were very alluring - transactions, persistence, security, transparency, etc. - and baked directly into the platform. Unfortunately, there were two glaring problems. The development model was complex and it was not well understood.
It was a number of years ago, but I recall vividly my first experience with EJB. I arrived on the team mid-way through their development effort. At that point, they had more than 100 entity beans, the localhost environment took more than four hours to start-up, and problems were rampant. I stuck around for three weeks before I got the hell out. The project wound up getting cancelled. Developers were able to easily understand the EJB programming model (especially with all the code generation wizards), but lacked the design wisdom to use EJB effectively.
These lessons serve as examples of the difficult road that lies ahead for OSGi, and specifically, modularity on the Java platform. If the development model isn’t understood, with principles and patterns that guide how developers leverage the technology, the benefits of the runtime model will not be realized.
I’m an advocate for OSGi, and firmly believe that modularity is a key component of agile architecture. There is a need for modularity on the Java platform, especially in developing large enterprise software systems. But if we do not begin to understand how to design more modular applications today, we’ll face significant challenges when platform support for modularity arrives.
What We Should Do Right Now
It’s important that development teams start modularizing their applications, even if they aren’t deploying to an OSGi runtime. How can we do this? We know a lot about the OSGi runtime model. It’s likely the platform we’re using is leveraging the runtime model internally, even if it’s not exposed to us. We know the unit of modularity is the JAR file, and we can start modularizing our applications today by emphasizing the JAR file as the unit of modularity.
I provide some insight to how we should go about doing this in my post On SOLID Principles & Modularity. Of course, these are simply top level concepts. There are numerous principles and patterns that provide additional guidance, and I hope to share many of these with you over the coming months. Out of this, I’m hopeful that tools will continue to evolve that help aid the development of modular software. For example, tools that provide important refactoring capabilities to help improve modularity.
Of course, the intent of modularizing our applications today is not so that we are able to take advantage of OSGi upon it’s arrival in the enterprise. That’s simply a positive side affect. The real value is the modular architecture that results.