You're walking. And you don't always realize it, but you're always falling. With each step you fall forward slightly. And then catch yourself from falling. Over and over, you're falling. And then catching yourself from falling. - Laurie Anderson

Monday, April 20, 2009

It’s been awhile, and things have changed again. JSR 277 is dead. JSR 294 is alive and well. IBM almost bought Sun. Oracle actually did. And Jigsaw is on the horizon and appears to be on a collision course with OSGi. The multi-module-verse. Like the parallel universes idea, Sun’s introduction of Jigsaw seems to create a significant fork in Java, with OSGi bundles in one version of reality and Jigsaw modules in another, forever isolated. Which begs the question: which reality do you want to inhabit? Better decide fast and jump the right way; the future of your code may depend on it.Are we really going to be forced to choose? The answer is unfortunately yes, as things stand today. Each module system has its own model for deploying, loading and resolving dependencies across classes, and they won’t know how to share. So if you package your classes in a Jigsaw module, but want to use classes packaged as an OSGi bundle, you’re SOL. And the same is true in reverse. Heavy sigh.As Neil Bartlett pointed out, one solution to this problem could be an acquisition that simply kills off Jigsaw, replacing it with OSGi. And sure enough, an acquisition has been announced.

But it would be a mistake to jump to any conclusions at this point on the future of Jigsaw.

Not only is it way too soon, it is also not as clear a choice as some would have you believe: Sun does have some valid reasons for building a simple module system for the JRE itself.

Where things get really contentious is when that same module system becomes the default choice for all developers. And the “our way is right/we know better” arguments flare up. But there is no “right” way—as with most software, different situations require different trade-offs.

Of course, we do have a standard model for solving this problem: a common API that enables different implementations. And we should use it here.

I won’t predict the life expectancy of Jigsaw, but one thing is crystal clear to me: the Java platform needs an abstraction layer for module systems. One that makes it possible for different implementations to exist, simultaneouslyand/or over time. One that provides a meaningful way for those implementations to share classes, so developers are not forced to make a potentially risky commitment. And one where a JVM vendor, or anyone else, can craft an optimized solution without shattering the universe.Even if we could all agree on a single module system, an abstraction layer is still the right thing to do to help future proof the platform that so many of us depend on. It's just good software engineering.If there is anything I'm sure that we should kill, it's the "us versus them" divisiveness that has dominated this space for so long.

I'm also a little unclear on the need for this abstraction. A module system is the place where abstraction happens, it shouldn't itself be abstracted. And even if one accepts the need for it, don't we then need a meta-abstraction over abstractions for module systems? And then a meta-meta... okay I'm getting silly there but perhaps you see my point.

OSGi is already a specification rather than an implementation, and it's handled evolution of that specification quite well (R1,2 and 3 bundle still run under R4). It's not perfect and some of Sun's ideas in Jigsaw should be incorporated -- but, incrementally rather than by reinvention.

In Java we do love to create abstractions and endless choices. Witness the number of web frameworks, for one thing. But a very small set of things need to be singletons in order to hold the platform together... for example could we live with two different JVM specifications? It seems to me that the module system should be one of those singletons.

I hear you guys. But we're actually talking past each other a bit here, since I haven't yet shown exactly what I'm talking about. I will soon.

My focus is on integrating modularity into the JRE, with APIs in the core library for module storage, discovery, metadata/data access and class loading. The point is to decouple tools and runtimes (e.g. IDEs, containers, etc) from the details of module storage, lookup, dependency resolution etc, etc. For example, a compiler should not need to have any knowledge of how a module’s bits are stored; today it has hard-wired knowledge about the jar/zip file format. Nor should the JVM launcher need to understand how to set up class visibility (e.g. via a class loader delegation model).

These and related issues are all forced to the surface when you want to modularize the JRE itself.

Perhaps we can just directly use OSGi APIs for this purpose; I do understand that many OSGi advocates would like to see this (and that Harmony apparently does so). And maybe it will end up being the right thing to do, but… I want to step back and take a slightly broader view first. If there exists a reasonable way to fully support OSGi without tying the JVM and the core libraries directly to it, it would be irresponsible not to explore it seriously. <insert your favorite argument against tight coupling here>

We all know and appreciate the strengths of OSGi (or at least most folks who are likely to be paying attention to this thread do :^). But it too will change over time, and I don’t think it should be constrained by how the JVM/JRE has used it. Neither is it always going to be the perfect solution for every circumstance.

I’ve been around the block too many times to think that there exists a one-size-fits-all solution, to anything in software (or life, for that matter). And given the astonishing rate of change in our industry, and the importance of the Java platform to it, we need to be a bit dispassionate—maybe even a little conservative—about any given technology.

OSGi as the important/dominant module system implementation? Absolutely. Staking the future of Java to its APIs? Maybe we need to consider a different story.

My problem is that we already have too many alternatives. True, alternatives are great when they are recognized as choices, but as Consultants and Architects they are akin to the never ending day.

Go to any 5 shops and you will usually find 5 different frameworks, 5 different methodologies, and 5 different implementations all doing the same thing. This one uses Struts, that one JSF. This one Spring MVC, This WebMethods and Velocity, or Tapestry, or FrameMarker, etc. Now we want two or three module systems. Geesh!! Will this insanity never end?

One of the reasons some shy away from Java is that Java is so convoluted and the choices so grandiose, the average developers and newer IT people, find it too daunting and overhwhelming. No not the language, no not the libraries, but the endless and constantly changing choices or "souo of the day"! Java has become the constantly moving target that is never stationary or immobile.

Whatever framework or methodology you adopt today you will have to learn all over again tomorrow. Its hard to get work done when you are tasked once again to learning a brand new way to write a Web Application or a Server Side Service application.

I live Java and it has been my primary development language for years. But I do wish we could find a good overall framework and stick with them for at least a couple of years.

Great strides have been made with modern Java much to the betterment of the language and tools. However I do wish for some of the Cobol days where you had time to take a least a small break!!

I totally agree on this last comment.Whenever you go to a new project you enter a new brand new learning curve for a new technology. What a waste, experienced programmers that never get to reach top-productivity

'And the “our way is right/we know better” arguments flare up. But there is no “right” way—as with most software, different situations require different trade-offs.And sometimes better is the enemy of good ... :-)

Spending ten years of my life specifying a module systems have given me a healthy respect for this subject area. However, hard I try, specifying a multi-module system system is way over my head. By definition, a common API for a multi-module system system will be a module system in itself that will require the specification of its semantics and thereby constraining the solution space to the current (limited) understanding of the problem domain.

Illustration: In the 90's CORBA introduced Interface Definition Language (IDL) which was designed to be language independent. Anybody that tried to use Corba with Java knows how awkward it became because it encoded the then popular C++ language concepts. Output parameters anybody?

I could not agree more that for each situation you can design a more optimized solution than OSGi could ever dream to provide. However, the fragmentation kills the most important thing of a module system: the common ground that let's us compete and collaborate, furthering the industry. Singletons are usually bad, but somethings get their value from being a singleton. An in the OSGi case, we have a singleton that is actually a spec with many mature implementations ...

So it is not ours is bigger or better, as you state. What bugs me is that we have an almost perfect situation: a single popular module system running on all Java environments, but instead of adapting this to the diverse needs, we spent all this energy to destroy this advantage and struggling to find solutions to self inflicted pains.

And yes, I am sure that in a couple of years better ideas will come on the horizon that will be too foreign for OSGi to integrate (and thus for any multi-module-system-system under which OSGi could run). When these ideas provide enough advantage, people will abandon ship, and that is fine. However, at that time we'll understand the next big idea and can optimize for it. Trying to design a system that could already integrate these future ideas? Hmm. Done that and failed every single time. Isn't it a law of nature that the next big idea is unpredictable?

Just to clarify the current issue in JSR 294 that I guess triggered your blog. JSR 294 was supposed to focus on the module keyword that provided restricted accessibility, the visibility aspect was handled in the now dead JSR 277 and moved to Sun's project Jigsaw. I always made it clear I opposed project Jigsaw and JSR 277 because it fragments the Java world for no reason I can fathom. Unfortunately, suddenly Jigsaw is the RI for JSR 294 and Sun is putting Jigsaw module dependency semantics in the language through JSR 294, which was out of scope of the JSR and my collaboration agreement. Worse, OSGi is also allowed to play, but only tunneled through the semantics of what Jigsaw provides.

JSR 294 was intended to be about the module keyword, not a module system. I think I understand the module accessibility issues sufficiently enough to work on putting this concept in the Java language (though there is lot of hard work left). And even better, I expect this module keyword to be a boon for OSGi bundles because the VM could enforce the bundle boundaries. So, working with IBM, Sun, Google, Yahoo, Oracle and others on this in JSR 294 is actually interesting and fun.

Anyway, Oracle seems to own Sun soon. Wonder how you guys will solve this puzzle :-)

My comment on your blog was intended to convey that "the OpenJDK project called Jigsaw ***CONTAINS*** both the Reference Implementation of JSR 294 and the design+implementation of the Jigsaw module system."

This is exactly analogous to the OpenJDK project called 'Compiler', where javac lives long-term. 'Compiler' hosts a single codebase that contains the Reference Implementation of the Java language and also an implementation of a class library. You know the latter as 'classpath'. The JLS doesn't mention it, but naturally its code lives near the Reference Implementation of the language.

The Jigsaw module system is effectively an upgrade to 'classpath', so its code lives near the upgraded-for-294 Reference Implementation of the language.

Sun made mistake when add java.util.logging into JDK. They should add interfaces for logging system instead - like SLF4J. Without SLF4J it is very hard to write logging info correctly because some libraries use log4j, other - java.util.logging, other - someting different. And we have to spend a lot of time to make workaround and gather all log's in one logging system.

That is Sun architect's fault.

Same mistake is Jigsaw. There should be ONE interface, but not implementation of that interface because in java interface give you more flexibility that implementation.

So may be Jigsaw can solve more problems but for better future of Java is have to die BEFORE Sun can put it into JDK. And "java.util.logging" is zombie that can not die, but can not live also. May be Oracle will kill this zombie...

To the last-but-one commenter: programming to an interface rather than an implementation is the cornerstone of object-oriented programming. Where suitable interfaces are missing, we should invent them, I agree.

To the last commenter: if someone invents technology X, and later someone else invents technology Y that improves X, then what do you call it when supporters of X complain about Y? Not Invented Here.

@Neal: "A module system is the place where abstraction happens, it shouldn't itself be abstracted."

A module system is the place where encapsulation happens.

Even with a singleton module system DESIGN that provides encapsulation, there is still a benefit in abstracting over implementations of that design so that tools can use a common interface to access encapsulated elements.

The JVM Spec is completely analogous to Bryan's proposal. Compilers can have different implementations and emit different bytecode (even for the same source language constructs!), but there's a standard storage interface for bytecode called ClassFile. Raise that up just one level: what would a standard storage interface look like for ClassFiles?

I build software, mostly in Java these days. I'm currently at Oracle, and have worked at Apple, IBM, Taligent, and AdForce in the past. I often play the role of "architect".
I'm on the Expert Group of JSR 294 (and was on 277 :^).
Mandatory Disclaimer: The views expressed on this blog are my own and do not necessarily reflect the views of my employer.