(Before we get underway, I want to make the point that all of this is based on my current understanding of the positions of both the OSGi folk and the current plans for Jigsaw. I’m not an expert in either, so there may well be egregious lies in this post. Informed comment from people who are an expert in either technology would be very welcome.)
Technologists don’t possess crystal balls. Early releases of technology platforms often have problems in them that are not ironed out (or even discovered) until much later.
One example of this is the Java platform’s lack of generalised modularisation and dependency management capability in the core. Sure, there are jar files, and as a basic means of shipping around units of functionality which are larger than a class, they’re OK.
However, when dealing with larger systems, the model of “just ship around a bunch of jars and manually manage the dependencies” starts to break down. What’s needed is a way to automatically manage the dependencies between functional units, via some metadata which is shipped within each unit.
This is where systems like Apache Ivy and Maven come from – they run outside of the core platform and automatically manage a repository of jar files. Build and runtime dependencies are then much easier to manage – all the jars are in one place. However, note that the platform doesn’t provide any support for these platforms out of the box – a classpath still has to be managed for start scripts, etc.
What would be better is if the platform provided for automatic management of dependencies in the core. Both of the mostly widely used systems broadly agree about which relationships between functional units need to be expressible, so there’s no major disagreement about what needs to be expressed.
The simplest cases are that a unit needs to be able to say that it requires:
- a particular version of a certain other unit
- a particular version or anything higher
- any version within a given range.
Dependencies should also be able to be marked as mandatory or optional, and different isolated contexts within the same JVM should be able to have different, incompatible versions of the same unit.
This much is basically agreed upon. Where the different viewpoints diverge is over what constitutes a functional unit, and at what stage of platform startup the dependency management and modularity functionality should kick in. The two big schools of thought are the OSGi view and the Project Jigsaw view.
- Unit of sharing should be the package. This reduces conceptual burden on developers to learn a new model and is simpler.
- Dependency management should start once the platform is fully bootstrapped. This allows the benefits to be brought to any compliant installation, and doesn’t require changes to the core platform.
- Unit of sharing should be a new concept – the module. This is “larger” than a package, and packages can also be split between modules.
- Changes should be made to the core, and the platform itself should be aware of module dependencies as early as possible. This is more work, and requires more co-ordination between implementations, but has potentially has big wins (quicker startup time, smaller footprint).
Which should you choose for your application? Well, Jigsaw is still being developed, and won’t land as part of Java 7 – it’s targeting Java 8. OSGi is a production technology, used in a surprising number of places (if you’ve ever used Eclipse, you’ve used OSGi technology, you just probably weren’t aware of it). However, it is still maturing – there are gaps around tooling, and there are gaps in the standard which has led to different approaches between vendors, with regard to e.g. bundle deployment.
If you want to learn a new technology, then Jigsaw is still very new, and a moving target, whereas OSGi is here today. On the other hand, unless you have a clear benefit from deploying something like this today, it may be preferable to live with the pain of Ivy/Maven and wait for the space to mature.
Finally, as a modest proposal, let’s talk about deprecation.
Java has always been bad at deprecation. We’ve known that Thread#stop and friends were the wrong thing to do for a very long time, but they’re still there, hanging on as deprecated methods. In the current setup it seems impossible to do anything to remove them. With a wide-ranging modularity solution, such as Jigsaw, in place – could we produce a release of a core module which removed the likes of Thread#stop and Object#finalize ?