Java 9 Incompatibilities

Last year I took a quick look at the newly released Java SE 9 but wanted to delay updating until the corresponding NetBeans version was out. Nothing happened, so that’s the first incompatibility to discuss, followed by JavaMail and JavaFX issues.

NetBeans MIA(pache)

After four months NetBeans is still in Apache incubator limbo with no sign of an official Java 9 release appearing anytime soon. So rather than waiting for who knows when, I decided to switch to IntelliJ IDEA which has already had three point releases during the same time period. IntelliJ originated as a commercial product but today also offers a free open-source community edition that’s perfectly sufficient for Java development (and of course Kotlin).

There are some drawbacks compared to NetBeans: the IDE is slower, with noticeable delays even on a beefy machine; and its greater flexibility results in a steeper initial learning curve. On the upside, IntelliJ is a good deal more powerful and professionally polished than NetBeans. It’s a relief to finally have a code analyzer that produces sensible reports out of the box, for example. I don’t think I’ll regret this involuntary IDE switch.

JavaMail vs Modules

I had dismissed the issues covered in this detailed Java 9 Migration Guide as “fairly arcane.” Turns out I was wrong. The section “Dependencies On Java EE Modules” lists various APIs that were once upon a time copied from Java EE to SE for developer convenience, and are now in the process of being removed again (JEP 320). As a first step toward this, Java SE 9 hides them by default.

The non-arcane dependency I discovered concerns JavaMail, a popular email and messaging framework. JavaMail depends on java.activation which happens to be one of those newly invisible Java EE modules. The JavaMail FAQ already adresses this issue: every startup of a Java SE 9 application that uses JavaMail must contain the command line flag --add-modules java.activation.

This workaround is rather unpleasant. The command line gets lengthy, it’s easy to forget this switch, and users can no longer simply double-click on an executable JAR file that needs JavaMail. Moreover, the --add-modules trick won’t work once the hidden modules have been removed from a future Java SE release.

JEP 320 recommends a better solution: deploy standalone libraries for any required hidden Java EE feature. For java.activation, a complete reference implementation (version 1.2) is available on the recently established Java EE project on GitHub. You can get the same version from Maven. (Strangely, JEP 320 links to a specification-only Maven artifact, and the JavaMail documentation to an ancient Sun download intended for Java 1.5!)

JavaFX vs Java SE 8

Java SE 9 is fairly new and can cause update headaches thanks to the new module system, so for the near future it’s safe to assume that most Java installations will use SE 8 at best. Let’s have a look at the various version configurations with regard to Java applications.

  1. Creating and running an application using the same Java version is unproblematic, of course.
  2. Creating an application with JDK 8 and running under Java 9 generally works, except for module-related failure cases like the one discussed above.
  3. Creating an application with JDK 9 and running under Java 8 should work, using the appropriate javac switches (-source/-target or now --release). There is one glaring exception: JavaFX.

If you try to build a JavaFX application under JDK 9 while targeting Java 8, any attempt to resolve any JavaFX type will fail and compilation will abort. Amazingly, this is by design! Oracle’s David Holmes explains the situation on the OpenJDK mailing list:

JavaFX is an extension provided as part of the JRE. The docs for --release say:

--release <i>release</i>
    Compiles against the public, supported and documented API for a specific VM version.

I’d say that an extension does not fit that description (though I dislike the description as it refers to the VM). So yes you will need the fx jar file available.

If you want to target JavaFX 8 from JDK 9 you need to link against the actual jfxrt.jar from JDK 8. I’m sure quite a few JavaFX developers will be surprised to hear that they were actually using an unsupported extension to Java SE 8. Oracle’s Jan Lahoda provides some further information:

For --release <= 8, the historical data used by --release contain class[es] for the default javac bootclasspath for OpenJDK, which does not include JavaFX.

For --release >= 9, this will probably need to be different (currently, --release 9 is supposed to include JavaFX if JavaFX is in the runtime image).

The “resolved/fixed” issue JDK-8188823 seems to indicate that JavaFX will indeed enjoy proper backward compatibility from Java 10 onward. In the meantime you might as well stick with JDK 8 for JavaFX development that needs to target Java 8.

Java AWT vs Font Leading

While porting my Class Diagrammer to Java SE 9, I found yet another incompatibility. It seems Java AWT used to have a bug where the recommended leading (interline spacing) of some fonts was ignored, i.e. TextLayout.getLeading always returned zero. As it happens this was the case for Adobe Myriad Pro which I use in my own class diagrams. The new text layout does look better but can increase the height of text blocks so much that I had to rearrange elements in a number of diagrams. This change may affect any precise text layout with AWT/Swing. (added 2018-02-15)

4 thoughts on “Java 9 Incompatibilities”

  1. Unfortunately when it comes to JavaFx Java’s compatibility principles got thrown out of the window with a vengeance, and that includes both directions. Even ControlsFx, one of the better known community projects hasn’t yet managed to provide a fully working Java 9 version, with various issues still remaining and giving up support for some controls entirely (SpreadsheetView). I’m curious to see whether the future will change this ecosystem instability, I somewhat doubt it because problems are baked into the design. Unfortunately, in contrast to Swing, the main design focus with JavaFx was modern Layout (maybe good), and inclusion of web like technologies like css and xml layout description (maybe not so good), rather than API extensibility. And since everyone is thus using hacks of internal implementation details to get anything meaningful done, the whole ecosystem is in a state of ever fragile flux.

    1. Thanks for bringing up ControlsFX, it is indeed quite popular though I’m not using it myself. I just found the Java 9 discussion mentioning the basically abandoned SpreadsheetView. The JavaFX situation does look pretty dim at the moment, especially since Swing finally got high DPI scaling in Java 9. With Java 8 I thought Swing would be obsolete but now I’m no longer sure.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.