In short, not much. At least, externally visible. There's the possibility that it's a duck, with limited visibility on what's happening above the surface but furious paddling underneath; or it could be an iceberg with a similar differentiation between what's externally visible and what's under the covers. (Let's just hope there's no Titanic passing close by...)
In my previous post on JSR294, where to misquote Mark Twain "The news of JSR294's death has been greatly exagerated", it seemed that JSR294 is alive and well. In the jsr294-modularity-observer list, I triggered a discussion on the inactive status (which turned out to be an automated red herring). I got cited for spreading misinformation on the web:
It has come to my attention that someone is spreading false information with respect to JSR 294 [1,2].
Frankly, there are too many cleverly-worded points in this misinformation to address individually here. The observer list remains available for any observer to send questions and comments to.
The "inactive" flag set on JSR 294 by the JCP Program Management Office is unfortunate. I explained its origins to Peter Kriens earlier today. It will be removed as soon as I publish an Early Draft Review, as per PMO rules.
I expect to publish an EDR within days [AlBlue: of 11th Dec 2009], and am confident it will meet the Expert Group's approval.
It should be noted that upon receiving updated information I edited in place both of the articles; and in the InfoQ piece, I specifically referred to JSR294 as 'inactive' although the blog post took its title from the well-known phrase The King is Dead! Long live the King!, also the title of an Enigma album. So both posts now correspond to reality, cleverly worded or otherwise.
But what of the promised EDR? Days turned to Weeks; Weeks turned into Month(s), and Sun turned into Oracle (or is about to be). Yet there's still no sign externally that an EDR has been published, nor has there been any info to update on the public JSR 294 page. The easy conclusion to jump to is that the EDR is delayed (whether through choice, accident or unexpected event is speculative). Either way, there has been no EDR to speak of.
Meanwhile, Alex Buckley has published version 0.1 of the Project Lambda JLS draft, along with follow up comments there. Arguably the additions of lambdas is a more important end goal to Java than an incomplete module specification; so perhaps that is a better focus. Or it could be that the Oracle/Sun merger, now that it's finally about to happen there may be a culling of useless JSRs. Jigsaw will still continue, but other than the addition of the
module package-like protected interface to fields – which arguably OSGi already does by virtue of its exported packages – there wasn't much overlap or use with JSR294.
Incidentally, speaking of Jigsaw, there's a new proposal for a Jigsaw module-file format. Rather than using a standard JAR for containing data, the module-file format is a brief header (with some generally useless information), the (uncompressed)
module-info.class file (which turns up from time-to-time in JSR294), followed by a Pack200 representation of the rest. The idea is to be able to parse some information from the module before it's all finished downloading (JARs are based on the ZIP file format). ZIP's standard reliance on the Central Directory at the end means that in order to parse a ZIP ifle, you need to jump to the end to be able to parse it (and in addition, be able to figure out all the intervening chunks). Arguably, there's nothing that would prevent the central directory being written out first, but this tends not to be the case for automatically generated headers. Tools that introspect a single entry (like the MANIFEST.MF or INDEX.LIST) might be able to guess at the first two entries (which, after all, have the data and filename) and most JARs are built with the MANIFEST.MF up front. In other words, we don't technically need to download a whole OSGi bundle to find out what it's dependencies are too.
What's more interesting, is that one of the goals for moving the module dependency to executable code (rather than having a declarative specification of the OSGi bundle, for example) was to allow code to extend the dependency list. Yet in the
module-info class case, if that refers to any non-local classes (such as those that are coming down in the following Pack200 JAR file) it will either (a) not be able to create its dependency list, or (b) have to wait until the entire file is downloaded before having that information. Flexibility can be such a double-edged sword at times.
(It's probably worth noting here that Pack200 completely reorganises the layout of the JAR file - it's a non-streamable format. You have to load the entire file in before you can even extract one component, so if you have Pack200 JARs – either as part of a P2 update site, or as part of a Jigsaw module – you have to load the lot before you can do anything. (And that's aside from problems with how you compile module-info.java in the first place.)
So, we all still wait to see what the outcome of the JSR294 EDR proposed proposal is. Alex was confident in its adoption, so perhaps it's been trimmed down to just a single keyword; though the thorny issue of irrational version numbers, even as Semantic Versioning is already the de-facto standard, still holds. As Stephen J. McConnell noted, a version numbering system that permits “
point-free @ braindead” and “
point-free @ pathetic” as valid (but yet incomparable) version numbers is one that really means nothing at all. And yet, even though the spec offers a free-for-all naming convention (for both the module name and the version number), it mandates the @ be used – an operator overloaded with annotations in a Java class. It seems that whilst JSR294 is supposed to be independent of Jigsaw, it's firmly driven by Jigsaw's requirements.
Interestingly, a recent update by Alex Buckley on the difference between JSR294 and module systems, tries to focus what JSR294 is supposed to deliver – language and VM features for the benefit of module systems such as OSGi and Jigsaw. Although it would be tempting to read too much into the PDF at the moment, the key is the module-level visibility (without actually defining what a module boundary is) is encoded in the
.class files. A generic way of specifying modules, whilst ignoring the
module-info.java and the versioned dependencies that introduces, seems like a necessary step towards source-level module awareness.
One could argue, though, that this is entirely pointless. The goal of a module system is to express (versioned) dependencies of the things you depend on. Whether a field is accessible or not, or whether it's enforced by the VM at runtime, is a bit of a moot point. Indeed, OSGi already provides this out of the box (at package-level granularity) by preventing you from accessing classes that are not visible. And if you have the Java source file for your code (to put the restricted
module keyword in) then you can just as easily move the code into an internal (non-exported) package. Module-crossing boundaries (think Eclipse's 'internal' or 'friendly' classes) are a use case which is not used well at the moment; they're exported, but not really supposed to be used by other bundles. Having a
module keyword, such that classes in the
JDT packages are all in the same
module, might provide a way of sharing internal details without having to expose their innards to the rest of the world.
But in reality, internal classes (or modules spanning bundles) are themselves a sign of a problem, rather than a symptom which should be treated. Having internally shared code between (say) JDT and JDT UI is the problem; get rid of that, and you don't need to have bundle-spanning-modules.
Ultimately, JSR294 is a tricky thing to solve. Sun want to have a module system without OSGi's so-called-but-not-qualified 'problems' (more realistically; one developed in-house to avoid intellectual property rights), whilst OSGi is the de-facto standard module system for Java at the moment. Given OSGi's more restrictive nature (particularly in the form of version numbering) makes a combined proposal – like the earlier Simple Module System – less likely to be acceptable to both parties.
Of course, the people who ultimately get hurt by this are the Java developers of tomorrow. There won't be a format that is accessible to both OSGi and Jigsaw module systems, which means developers will have to pick which one to support. Quite aside from the fact that OSGi bundles are already backwardly-compatible JAR files (and thus can be used inside or outside of a module runtime), the choice of using Jigsaw is to lock yourself into one manufacturer's VM and from an as-yet-unreleased point forwards. It's not difficult to do the math of where the biggest customer base is.
Finally, because someone always mentions it, OSGi is not too complex. Actually, arguably it makes development easier – particularly when considering things like the Blueprint service or Declarative Services, which provide a dependency-injection way of configuring modules without needing any code references to
org.osgi packages in source. This, of course, makes them trivial to mock, both at testing time and then later at run-time as well. And, as noted in December's Bundle.update, the Enterprise Expert Group Draft 4 was previously made available and is nearing completion. This will give an OSGi way of binding JNDI references and JDBC drivers to running OSGi applications, making an OSGi runtime into a JavaEE type container with late binding of databases. Whilst the spec isn't yet finished, the direction of the group (including the WAB web bundle format) will make it trivial to deploy web-based applications that lean on the OSGi runtime.
What is complex, however, is the concept behind modularity. How you split apart a system into smaller modules, how to reference the components' dependencies, how they hook together in the face of a non-flat classpath are all problems that Jigsaw will face just as much as OSGi will. Problems reported between “Hibernate and OSGi” will be just as applicable as “Hibernate and Jigsaw”. At least OSGi was defined with services in mind (allowing cross-module communication to occur); it's just not clear whether Jigsaw will discover that down the line or not. Factories (like the URL parsers) in the JDK are currently in the same module as the net stuff anyway; so that's an internal reference. But you can bet that a Jigsaw module ringfenced around the Java net classes will face exactly the same problems of how to depend on third-party supplied factories (c.f. JDBC, XML parsers...) in a non-flat classpath. Of course, the way it's likely to happen is by using a non-non-flat classpath, or exactly the same classpath as we get outside of module systems at the moment. However, a compile-time checked classpath but with a flat runtime classpath (albeit one with 'module' keyword checking done on the fly) is going to prevent any kind of duplicate version being loaded into memory, or dynamic reloading of classes for that matter.
Modular Java is complex. Solutions to complex problems can be simple, or they can be complex; but if you don't understand the problem, then everything looks complex. Kirk Knoernschild recently declared that 2010 is the year of Java Modularity and followed up with Java Modularity: Time to Set Sail. Modularity is something that we all need to pick up, regardless of which module system is needed. Ultimately, it may all boil down to today's Oracle/Sun conference:
So it may come down to this. The future of OSGi, Jigsaw, and modularity on the Java platform comes down to the direction that Oracle intends to take Java technology going forward. Of course, their decision will have a tremendous impact on the entire Java ecosystem. We should have direction sometime soon. Time to set sail!