Yesterday, Mark Reinhold posted the first public draft of the future of modularity in Java. Unlike the previous iterations of JSR294, the discussions of modularity in Java have taken place outside of Sun/Oracle's closed doors and involved others with a stake in OpenJDK, such as IBM and other members of the Java SE and Java EE communities, as explained in Mark's blog post on the subject.
As it is a draft there are a handful of issues that still need to be agreed on but it represents the consensus of what modularity in Java should look like. And with IBM being involved, there's more emphasis on interoperability with OSGi than there has been in the past.
What's interesting with the requirements is that the intention is to build upon the ServiceLoader and ResourceBundle that currently are not well behaved in the face of modularity, so that those who want to use a standardised pattern can still take advantage of the modularity without having to be concerned with the details. Currently, ServiceLoader has problems with multiple classloaders.
One of the key goals of enabling modularity in the JVM is to enable the splitting of the JVM libraries itself, which have grown to tens of megabytes in size over the years. (Scala, which doesn't deal with the concept of modularity, has almost reached 10Mb in size as well.) However, all classes in the JVM's libraries expect to be in the same ClassLoader
; and since OSGi has one per bundle, this wouldn't be a direct map. (OSGi does have the concept of fragments which insert themselves into the parent's classloader.) Being able to support a module system with a single classloader (and therefore, no dynamics) as well as one with a multiple classloader approach is part of the document's requirements.
Some statements are vague. For example, versions are required to be totally ordered, but there doesn't appear to be a consistent versioning scheme such as Semantic Versioning. And whilst it requires that the metadata be strictly defined (of which the version number is part), the contents of the version are left open to interpretation.
Another open issue is whether the module information should be available as compiled Java code, or a declarative external library. Whilst OSGi uses the existing MANIFEST.MF
file for encoding dependencies, the previous Jigsaw implementation compiled a Java class file to permit introspection through libraries. One downside to the Java variant is that it will make using the module system for non-Java languages harder (such as Mirah or JRuby).
This requirement looks to be contentious. Whilst noting that he hasn’t yet had time to read the full spec, JRuby lead Charles Nutter has already commented on Reinhold's blog
By requiring that there be a .class file, probably with annotations in it, the jigsaw modularity system unnecessarily restricts participation to languages that:
- Compile to JVM bytecode always before shipping
- Support the full complement of Java language constructs, like annotations at the source level
In other words, JRuby, JavaScript (Rhino), Smalltalk (various), Python (Rhino), and several other languages would immediately be excluded.
Going slightly further than just modularity, the proposal also talks about generic packaging systems (like rpm
and easy_install
) as a means of transporting Java runtimes to other systems, as well as web publication of the artifacts.
The proposal, whilst still a work in progress with unsolved issues, has attracted some positive reactions:
There are many, many good requirements in this document and Java will certainly gain from having these realized - if this is done in an open and inclusive manner.
Another good thing is that once modularization is part of Java SE 8, moving to OSGi will be easier than it is today. The biggest stumbling block for migrating an existing system to OSGi today is often the modularization of a system that wasn't created in a modular way in the first place. It's not an issue with OSGi per se, but with modularity as a concept. If you have existing code that is non-modular, it can be difficult to modularize it. With JavaSE 8 this problem will appear earlier in the development cycle which should help people design their systems in a modular way from early on. If you need more than the basic JVM module system then you can move to OSGi taking your existing JavaSE 8 modules and they will just work as-is - so migration will be a breeze. Then you can enhance the modules to take advantage of the OSGi benefits (see below).
It may be that the modularisation in Java enables the OSGi-lite pattern whilst encouraging Java library developers to annotate their runtimes with module metadata, which can then be consumed by OSGi runtimes. In any case, whilst there are some known disagreements, moving it forward in a compatible and sensible manner will benefit all Java (and JVM-based) developers in the future.
What do you think of the proposed modularity requirements?