Reasons Not to Mourn JSR 294
Alex Blewitt posted a pair of articles on his personal blog and on the InfoQ news site, about the “death” of JSR 294. It turns out that the obituary may have been premature, with the other Alex (Buckley, spec lead of the JSR) clarifying that the JSR was tagged as “inactive” merely for process reasons within the JCP, and that Sun had not in fact abandoned it (yet).
Nevertheless, even if not actually dead yet, the buzzards are circling. I for one will not mourn it, if and when it does die. Here, I explain why.
JSR 294 aims to add declarations to the Java Language Specification (JLS) to support modularity. The idea is for runtime modularity to be provided by OSGi and/or Jigsaw, and these module systems would be able to take advantage of declarations in Java source files to work out things like the contents of a module, its version and its dependencies on other modules. Ideally the declarations would also enable interoperability, so that (for example) you could use a Jigsaw module in an OSGi runtime or an OSGi module in a Jigsaw runtime. Then library authors would not have to compile, test and build separate deployment artefacts for each module system. Unfortunately JSR 294 in its current state (PDF warning) falls short of both these goals.
Let’s take a look at an example; here is how a module declaration might look if we are using Jigsaw (this example provided by Alex Buckley):
- module M1 @ 1.0 {
- requires M2 @ 2.0, M3 @ 3.0;
- provides M4 @ 4.0, M5 @ 5.0;
- permits M6;
- class com.foo.bar;
- }
Rather than explain immediately what this means, we will dissect its anatomy and see how else we might have written it. There are three parts: the new “module” keyword; the module identity which consists of the string “M1 @ 1.0“; and the directives section which is everything between the braces.
Here’s another example using a hypothetical module system called MentalModules. The following will be legal Java code in Java 7, if JSR 294 is passed in its current proposed form:
- module DogsDinner @ you_call_this_a_version?? for MentalModules @ @ {
- Valid on Tuesdays Wednesdays or Fridays;
- Except Public holidays in the state of Texas @ π; // Yes, that’s a pi!
- My favourite cheese is Stilton
- @ Believe_It_Or_Not_This_Is_a_Version_String_Also;
- Did you know that a shaved tiger still has stripes?;
- 私はイチゴのジャムが好き!;
- }
My apologies about the highlighting… my blog’s syntax highlighter couldn’t cope with such nonsense; neither will the one in your IDE. Anyway, how can this rubbish be valid Java? In fact the second example means just as much to the JLS as the first one does: nothing at all. Aside from some very light syntax rules (e.g., no commas) the contents of the directives section are entirely unspecified by the JLS. They are a little like annotations, except they do not need to be imported; instead, they must be understood by plug-ins into the Java compiler. This means there will need to be a compiler plug-in for Jigsaw and one for OSGi, and one for MentalModules too, if anybody feels like writing one. Library authors will have to decide early which module system to compile for, and under this system it will be hard to support multiple module systems.
Now take a look at the version strings. Alex’s examples look sensible enough — “2.0″ is a useful version string — but the ones in the second example don’t look so nice. In case you hadn’t spotted them, here again are all the legal versions used in the example:
you_call_this_a_version??(including the question marks)@- π
Believe_It_Or_Not_This_Is_a_Version_String_Also
Under JSR 294 versions are nothing but strings, again with some extremely light syntax rules. This supports Jigsaw’s anything-goes approach to versioning, and some commenters have found such liberal versioning attractive since it can accommodate, unmodified, all of the crazy versioning schemes used in the wild. But the problem is this makes it extremely hard for the importers/requirers of a module to depend on a range of versions rather than on a point version, so every tiny bugfix release of a module will invalidate all the modules that depend on it. There is not even a consistent way to calculate which of two versions is “higher”.
Let’s get back to the more sensible-looking example provided by Alex. Unfortunately even this declaration is as useful to OSGi as my deliberately nonsensical one. While the require directive could correspond to OSGi’s Require-Bundle, the provides and permits directives are meaningless to OSGi. Likewise any OSGi-specific directives we might think of to use with JSR 294 will probably be useless to Jigsaw.
So JSR 294 does not help to enable interoperability of module systems. It does not define any shared semantics for module versioning or dependencies. It merely provides a dustbin into which module systems can dump all their arbitrary and proprietary directives. For these reasons, I find myself unable to muster a tear at the thought of its demise.


