Modular Java BeJUG conference
The two presenters were Bert Ertman and Paul Bakker, both working for Luminis, Bert being an official Oracle Java Champion.
They began their talk by stating the following two trends:
- Applications these days are bigger and bigger and thus are more complex
- More and more teams adopt, at least partly, agile methodologies
Those trends bring new challenges along with them:
- dependency management to manage dependencies of the application on its libraries.
- versioning of the application that must fit with other enterprise projects which have their own, parallel, lifecycle.
- maintenance on the long term become difficult (“it’s difficult to refactor level 0 of a 20-story skyscraper”).
As applications are moving to the cloud, other non functional requirements enter the game too:
- As your users never sleep, you must deploy with 0 downtime.
- Deploying a big monolithic application on the cloud takes time.
- Customer-specific extensions that must be deployed on a Software as a Service application.
Modularity is the answer to those issues.
What is a module?
Every decent programmer must probably remember this from his classes: a good design has loose coupling but high cohesion.
Coupling is prevented through the use of interfaces and by hiding the actual implementations. Each module has its public and private parts and other modules cannot “touch its private parts”.
But then comes the issue of instantiating the actual classes. A popular way to solve that problem is to use dependency injection. But you can also do it with some kind of service registry which you can ask to provide you with an implementation of type X. Each module notifies the registry about the interfaces he provides implementations for and which interfaces he consumes. That service registry can manage multiple versions of interfaces and choos the best match.
With a little help of design-time modularity, we can thus tame the spaghetti syndrome of the most complex application.
When we analyse the same issues from the runtime view, the JAR file becomes THE unit. So how do we deal with module versioning and intra-module dependency management? How can we replace just 1 module at runtime?
The first part of the answer is: put the architectural focus on modularity! If you don’t group coherent functionality together, there’s no point using the second part of the answer. So that second part is: use a modular framework like OSGi (Jigsaw can be seen as an alternative to OSGi but is far less mature). But keep in mind that a modular framework is no guarantee, the key is a modular architecture.
How well does modular java play in the JavaEE game?
JavaEE is high level. OSGi is low level and provides no enterprise services (transactions, security, remote access, persistence, …) on its own. So you’re left with 3 options:
- Deploying enterprise services as published OSGi services.
- A hybrid approach with a classic JavaEE part + a modular part + a bridge between the 2 containers.
- An OSGi “à la carte” approach.
The first option involves application servers that publish their services as OSGi modules. Glassfish does that. There is now a concept of WAB (Web Application Bundle) files that are WAR files whose servlets are deployed as OSGi resources. A similar system exist for EJB bundles but there is no standard yet.
The second option can be implemented with Weld as CDI container to provide CDI inside the bundle and consume and produce OSGi services.
I’ll complete the description of the third option when I get access to the Parleys’ video (sorry, I ran out of ink at that moment and writing this article 2 weeks after the conference doesn’t help either).
Deploying to the cloud
The main concern here is that a modular application may involve hundreds of bundles. But hopefully, something like Apache ACE platform can help you manage this and gives you the option to redeploy 1 module at a time.
I won’t go into the details of the demo. The easiest is to wait the Parleys’ video as this will be far more interesting than me trying to write what I’ve seen.