Java’s Pre Modular Syndrome
After an odyssey of nearly 12 years Mark Reinhold’s dream of a modular Java VM seems to be finally coming home. I did played a role in this epic journey but last year, eleven years after the submission of JSR 277, I withdrew my membership of the JSR 376. I had no idea anymore what I was doing there. Initially there was an interesting functional overlap between OSGi and JSR-277 but over time it became clear to me that Mark, through the lens of the OpenJDK project, saw a very different problem then that my customers are facing. Mainly, since OpenJDK is at the bottom of the Java stack, it is in the unique position to not have any external dependencies; The build is more or less self contained. However, for most Java developers the three most important problems are dependencies, dependencies, and dependencies. Clearly, Mark is in a unique situation and that changes the perspective enormously. Only with this OpenJDK perspective does Jigsaw make any sense.
For example, Jigsaw requires that there is a single namespace for all packages and classes in the executable. That is, the package
com.example.foo can only be in a single Jigsaw module, even if this package is not exported by the module. This simplifies things considerably, having a single name space allows a complete application consisting of hundreds of modules to have a single class loader that stores the classes in a simple Map. Since I don’t know any rational reason why someone wants to design with split packages, overlapping private packages, and requiring different versions for the same class in OpenJDK, this restriction makes a lot of sense. A JVM modularized that way will truly be an improvement.
Another problem that has plagued Mark over the past 15 years is idiots (like me) that use classes like
sun.misc.Unsafe. Although these classes are clearly marked as implementation details their unique functionality (or plain convenience) made them important dependencies so that other VMs like IBM’s or JRocket had to include these private packages as well. This made it impossible for Sun/Oracle to improve their code base because it would break existing customers, who normally would object to this breakage. Since Jigsaw will break almost every non-trivial project anyway it was decided to go all the way. In Jigsaw modules are truly impenetrable, not even a
setAccessible(). It is hard to argue against this model if you want to keep your hands free. And since the JVM does not have to worry about silly things like dependency injection or other popular reflective patterns it has no cost to Mark. A clear win-win situation!
Cycles between modules are a bad practice. Since Mark controls the whole code base of the OpenJDK he can easily pick the decomposition that has no cycles. For example
java.base contains the highly circular dependent packages
java.io, etc. Since cycles are also more complicated to handle in a resolver (it saves you at least a Set), it makes a lot of sense to forbid them between modules in the OpenJDK.
Some people complain about lack of version in the modules (or the strange syntax) but I find that quite unfair. The OpenJDK has no external dependencies and it is always built as an atomic unit so what purpose would a version have? You only need versions when you have to track dependencies that change over time.
Sadly Mark did not survive the battles along the journey unscathed. He reluctantly added open modules to allow any framework in the Java eco-system to have a fighting chance. He also added the pre-deprecated
jdk.unsupported module because not having
sun.misc.Unsafe could likely bring down the internet.
So I am not sure I understand some of the criticism of Jigsaw. Mark set out to modularize the OpenJDK and he has spent the last 12 years creating tooling to do it. As far as I can see he did an excellent job for the OpenJDK. Why whine about lacking support for things like overlapping packages, versions, the total impedance mismatch between Maven naming, split package support, reflective access, and supporting multiple versions of the same class when they are all arguably bad practices for the OpenJDK?
So I highly recommend Jigsaw when you have, just like OpenJDK, no external dependencies in your code base. For the rest of us who wrestle daily with the myriad of, not always clean, dependencies in Maven Central and other repositories, OSGi provides a more enjoyable route towards true modularity. Just ask Eclipse, Sonatype Nexus, Liferay, Adobe EM, and probably many more than you think.