Jigsaw Finally Arrives in JDK 9
infoq.com
infoq.com
It seems adding modularisation to a product of the nature and scale of the Java API, while maintaining backward compatibility, is very hard.
http://openjdk.java.net/projects/jigsaw/spec/issues/
Of special note is Springs need for optional dependencies. Previously several other projects requested this but always got shot down by Oracle with "we didn't find any need for this in the JDK". AFAIK optional dependencies are still not planned.
http://mail.openjdk.java.net/pipermail/jigsaw-dev/2015-Decem...
In addition the SWT/AWT Bridge that Java Mission Control which ships with OracleJDK uses requires special JVM flags to run with break up modularity. I'm not aware of any plans to fix this.
Java currently doesn't have true packages. There's namespacing (com.companyname.abc.xyz), but it's all on a single classpath (java -cp). Dependency management like Maven gives somewhat of an illusion of packages. The end result of a Maven build is still a bunch of jars running with "java -cp".
For example, in Maven, imagine there's a json-lib 1.0 and 1.2. Library A needs json-lib 1.0 and Library B needs json-lib 1.2. Project X is using both Library A and Library B and when Maven tries to build, there will be a version conflict between json-lib 1.0 and json-lib 1.2. There are no good options at this point because the single classpath forces the selection of one version for json-lib. The developer has to either pick json-lib 1.2 and hope Library A can run with it. Or pick json-lib 1.0 and hope Library B can run with it. This is assuming Library A and Library B are external libraries that the developer has no control over and hasn't been updated in a long time.
With packages (Jigsaw), it's possible to let both versions exist in a project. It will be possible for Library A to be a package and use json-lib 1.0. And Library B will be another package and can use json-lib 1.2. During runtime, each package will have an isolated classpath and so the dependencies won't conflict. I'm assuming the Maven developers will update Maven to do this once Java 1.9 is released.
This will remove a big headache that currently exists for Java developers. The chances of a version conflict approaches 100% as the number of dependencies grows in a project.
The other thing that Jigsaw is bringing is modularizing the standard library as well. So if you don't want CORBA in your runtime image than you can leave it out.
And isn't that classloader magic?
Perhaps ignorance on my part.
Everyone rallied against OSGi because the strict modularity showed developers that in general their application wasn't as modular as they thought it was; and the fact that class loaders enforced that permissioning model showed where random Class.forName and module busting code lived.
Guess what? Those developers will have exactly the same problems with Jigsaw modules.
What Jigsaw will do is educate Java developers that the pain points are in strict modularity rather than any one module system.
And many more. Jigsaw also locks down reflection. In addition Jigsaw lacks many work arounds that OSGi has to get software working (fragments, buddy classloading, dynamic imports, optional dependencies, capabilities, …).
Honestly I have a hard time seeing any existing large code base work on Jigsaw.
They've taken enough to get to this point that adding version numbering isn't going to happen, but it doesn't rule it out adding it in the future. They did the minimum necessary to split out the Java libraries into different modules but no more.
If you want to have versioned dependencies, you have to work with a module system that understands versions, like OSGi.
Modules are not allowed to export the same packages.
Gradle's dependency tools help, but the best it can do is either flag an error or automatically de-conflict modules by always picking the newest version. If the version isn't fully backwards compatible, you can get deadlocked.
So for the first version I'd be happy to see this left to frameworks sitting above the module system, but I can appreciate other view points.
Currently if you want to deploy software running in the JDK, you're forced to pick up the whole JDK, which is terrible if you want to deploy as small a codebase as possible, especially because literally nobody is using Swing and AWT and Nashorn in server-side environments.
Meanwhile, currently if you want to use a module system that only deploys code you're actually transitively dependent on in Java, you have to roll your own with its own concept of dependency and versioning.
Meanwhile, currently if you want to depend on a library that's already deployed on a host, you get to discover it via the classpath mechanism, which has an element of.. randomness.. to it, and in some cases if you have two versions of the same class in your classpath you can get some very strange and hard-to-debug behavior. (I've had colleagues who wrote custom classloaders purely to work around this in the constraints of our dev environment) This combines especially badly with the ubiquitous use of 'discovery' mechanisms in enterprise Java such as static logger binding or classpath-scanning for annotations to find configurations and bean definitions.
Meanwhile, currently, the 'public' designation in a module means public to everyone in every module, and if you want to avoid that and go package-private or less, you have to be private even within other packages of your own module, since package-private is not inherited by subpackages (com.me.x and com.me.x.y do not actually 'inherit' in any sense). That is, there's no distinction between 'public' and 'exported' types.
Jigsaw attempts to address all of these. I haven't followed it closely enough to comment on whether I think it's the ideal solution, but, it's definitely the right direction if Java is to continue being used everywhere - which it is, because it's deeply entrenched and (while not as modern as some would like) it's getting the job done.
For example, I'll no longer be including the useless (for most Java apps) CORBA capability with my product. A server-side product will be able to exclude the desktop GUI API (AWT and Swing).
That is very unlikely. If you look at the java.desktop module (where things like AWT and Swing are) there are also tons of other things there like Java Beans. A lot of Software requires Java Beans at least indirectly (eg. Spring requires Java Beans). In addition there's the following dependency path. java.xml.ws -> java.xml.bind -> java.activation -> java.desktop A server side product is very likely going to require at leat one of these. The fact of the matter is that the JDK code is simply not modular enough.
What bothers me more is that things like Java Beans are in java.desktop.
The primary benefits are better security, encapsulation and the jlink tool that lets you build standalone app-specific bundled JREs.
• Don't have unused modules
• Don't use JARs as a format, instead using a much more optimised internal binary format
• Have various whole-program optimisations done on them, like removing the use of reflection.
• Can produce native Mac/Win/Linux installers/packages.
The last one is already a feature of Java 8 via the javapackager tool, but jlink makes it a much more powerful system.
First, I am worried that instead of being able to just assume that "all of Java is there", there will be "no we just did a minimal install". Second, after watching the video briefly, we may already have tools for most of what this tries to solve (Maven, Spring boot, etc). Third, I suspect that there's some sort of nefarious scheme by Oracle to start charging for "premium" parts of JVM.
My initial feeling: it works just fine now, don't fix it. Or maybe I am wrong and it will be great.