JDK 9 is less than three weeks away at the time of the writing and one of the burning questions is whether it has been worth the wait. Originally, general availability was slated for release in September 2016, then March 2017, July 2017 and finally September 2017. So, it’s taken some time, but when you update a programming language as a community, progress is slower than if a vendor does it single-handedly. There’s still work to be done, including bug fixes, which will come later.
Interestingly, not many Java developers seem to want to talk about Java 9. Red Hat, which occupies two seats on the Java Community Process (JCP) Executive Committee, wasn’t able to respond in time for publication, according to a spokesperson. (Red Hat and IBM have had differences with Oracle concerning what JDK 9’s modularity should look like, which is not surprising). A Cisco engineer using JDK 8 wasn’t even aware that JDK 9 was almost ready for general release.
Part of the problem may be that there’s not a lot of Java 9 information available yet.
“I was super excited about 9 because everyone’s talking about the whole Jigsaw thing. Then I opened up some videos and all the people on the video told me to wait. Based on their statements, the instructions I’ve read and examples of things online, I have to say the same thing,” said John Alexander, senior software developer at Internet marketing service provider Zeeto who’s been using Java since 2004. “I can’t justifiably tell anybody at my company we can switch over right now and get all the benefits. There’s going to have to be research done, which is kind of scary.”
Alexander Volkov, a business analyst and architect at online brokerage software provider Devexperts is wholly unimpressed.
“Actually, [JDK 9] has no super compelling features as almost every feature is outdated and is a ‘catch-up’ of Java as a language and a platform to what is already available somewhere else, be it other languages, libraries or platforms,” he said.
Software development management consultant Eric Madrid has been using Java since the first version. He sees value in Java 9.
“9 is unique in that a lot of the Oracle obligations have been fulfilled. This is the first release of Java where the community gets what they’ve been asking for,” said Madrid. “We’ve had some tooling, more modular design and the big one I’m looking forward to is native interprocess communication.”
In February 2017 Oracle published a beta draft of the Java Access Bridge Architecture. Java Access Bridge is a collection of classes and DLLs that enable interprocess communication among assistive technologies and Java applications.
“There a thing called the Twelve-Factor App, which is the de facto standard for scaling, configuring, deploying, coding and testing software applications. One of the tenets is scale and how you scale is through interprocess communication,” said Madrid. “You have a process running on one machine and I want to directly communicate with a process on another machine. There are native ways of doing that. Java’s never allowed you to interact with a process directly, you had to go about it another way and use different layers and databases and messaging systems and things like that, but this is Java’s first attempt at building native scalable design.”
The migration to Java 9 from previous versions will be more difficult than previous migrations because Java 9 has a modular architecture and previous versions have a monolithic architecture. Developers want to see Java 9 support in their favorite tools and educational material that can help ease the path to migration.
“Other releases were effectively turnkey. You could get your applications to stand up with minor adjustments,” said Zeeto’s Alexander. “That’s definitely not going to be the case with 9. Aside from extremely simple trivial applications, there is going to be work that needs to be done just to get your application to run as opposed to refactoring it to be 100% modular and following the new suggested conventions. That’s an interesting concept because this is kind of a big request for us as developers to do.”
Madrid has been experimenting with JDK 9 and says he would hesitate to migrate to it until there’s more support for it.
“I have an opinion against migrating because writing code is hard enough. You have to have the right reasons to migrate and so migrating for the sake of just going to 9 would be kind of silly,” said Madrid. The conditions [under which] I would want to use 9 is do I have free range on implementation [and whether] the things I like about Java such as Spring and OS support are ready for 9. I think there’s some level of soaking that 9 needs to have before it’s adopted by a larger community like any new technology, but I think it will be well-received.”
JDK 9 has a lot of small enhancements and there are a number of features from previous versions that have been deprecated or removed. Following are some things worth noting.
Modularity is a big deal
JDK 9’s modularity makes sense in an era where all things large are being broken up into smaller pieces. In JDK 9’s case, the modular architecture enables greater scalability down to smaller devices. It also improves security, performance and maintainability.
Modularization has been a multi-year effort that wasn’t ready in time for JDK 8, which is why it’s introduced in JDK 9. The modularization can be problematic for applications developed with the earlier monolithic versions of the language.
“The story is simple: Your application will break. How many hoops will it take to get it back online?” said Zeeto’s Alexander. “Modularization at this point is verbose and add complexities. Java 9 will diverge all future library releases as ‘lib-9’ and ‘lib-legacy’ and [that] will definitely impact the community.”
A module is a self-describing collection of code and data that can be combined with other modules to achieve different configurations including Java Runtime Environment (JRE). The JRE modularization simplifies application testing and maintenance.
JDK 9 introduces a link time phase which occurs between compile and runtime. It allows developers to assemble a set of modules into a runtime and customize modules as necessary.
The Java compiler (javac) and linker (jlink: The Java Linker) tools enable developers to specify module paths that locate module definitions. Java Enhancement Proposal (JEP) 247 enhances javac so it can compile Java programs to run on selected older versions of the platform. JEP 282 (jlink) assembles and optimizes a set of modules and their dependencies into a custom runtime image that can be optimized for a single program.
Also new is the modular Java ARchive (JAR) file which is a JAR file that has the module-info.class file in its root directory and a MOD packaging format that can include native code and configuration files.
The module system also has a more concise version-string format that distinguishes major, minor, security and patch updates.
Instant code feedback
JEP 222 (JShell) adds Read-Eval-Print-Loop (REPL) functionality to the Java platform, which has been a feature of other languages including LISP and Scala. REPL is an important addition to JDK 9 because it provides developers with instant feedback as they write code. The capability is helpful for programmers who are new to Java and for experienced Java developers who want to learn how to use an API, a library or a feature. REPL helps improve developer productivity by preventing errors early in development.
Improved JVM Compilation and Performance
JEP 165 provides compiler directive options to control JVM compilation. The level of control is manageable at runtime and method-specific. This new feature supersedes and is backward compatible with CompileCommand.
JEP 197 segments code cache, with each segment containing a different type of compiled code to improve performance and enable future extensions.
JEP 276 dynamically links high-level object operations to the appropriate method handles at runtime based on the actual types of values passed. While dynamic linking is not a new feature, the new capability provides a way to express higher level operations on the objects and methods that implement them, unlike java.lang-invoke which is a low-level API.
JEP 158 introduces a common logging system for all JVM components. JEP 271 uses this unified framework to reimplement garbage collection (GC) for consistency between old and new formats, though the consistency is not absolute.
To improve user experience, JEP 248 makes G1 the default garbage collector on 32- and 64-bit server configurations. It replaces the Parallel GC, which has been used for a very long time. The reasoning is that a low latency-oriented collector is better than throughput-oriented collector for its intended purpose (user experience).
Core library enhancements
JEP 102 improves the API used to control and manage operating system processes. The ProcessHandle class provides the process’s process ID, arguments, command, start time, accumulated CPU time, user, parent process and descendants. The class can also monitor the liveness of processes and destroy processes. With ProcessHandle.onExitmethod, the asynchronous mechanisms of the CompletableFuture class can perform an action when the process exits.
JEP 193 defines three different things. The first is a standards means of invoking the equivalents of Java.util.concurrent.atomic and sun.misc.Unsafe.operations upon object fields and array elements. In older versions, sun.misc.Unsafe.operations provides a non-standard set of fence operations. JEP 193 defines a standard set of fence operations to enable fine-grain control of memory ordering. It also defines a standard reachability fence operation to ensure a referenced object remains strongly reachable.
JEP 254 provides a space-efficient internal representation for strings. Previously, the String class stored characters in a char array using two bytes for each character. The new representation of the String class is a byte array plus an encoding-flag field.
JEP 266 is an interoperable publish-subscribe framework. Updates have been made to the CompletableFuture API and other things with the goal of continually evolving the uses of concurrency and parallelism in applications.
JEP 269 is a collection of APIs that are static factory methods to produce collections of immutable instances. The APIs simplify the creation of instances. For example list.of and set.of can take up to 10 fixed arguments. Alternatively, vararg can be used for an arbitrary number of arguments that pertain to lists and sets. Map.of is for a small number of key-value pairs. It does not use vararg.
“It’s taken 20+ years for Java to have this by default which is insane. It’s taken way too long,” said Zeeto’s Alexander. “The fact that I have not one but two different libraries installed across every one of our applications just to generate static lists poorly is very strange to me. I shouldn’t have to use a third-party library to generate a list like that. So, they’re late to the party, but I like it.”
JEP 269 makes lists, sets and maps easier, so what’s not to like? Perhaps the fact it’s a set of APIs rather than a standard, built-in feature of the language.
Java 9 support
At the time of this writing, Eclipse has a beta version that can be added to an existing Eclipse Oxygen (4.7) install. The beta provides the ability add JRE and JDK as installed JRE. With it, developers can create Java and plugin projects that use a JRE or JDK 9. They can also compile modules that are part of a Java product. In addition, there is beta support for Java Standard Edition (SE) 9.
In a March blog post, IntelliJ announced that IntelliJ IDEA 2017.1 provides support for Java 9 modules including code completion, quick fixes and help. The blog includes a nice walkthrough of a “Hello World” example. It also notes that Java 9 modules must correspond to IntelliJ modules and that the dependencies for both Java 9 modules and IntelliJ modules need to be declared. In July, IntelliJ announced new improvements that aid developer productivity. One of them is the color-coded Java Module diagram. It enables developers to visualize modules and their dependencies.
Madrid is a firmly committed IntelliJ user because it enables him to be more productive than he would be otherwise. Like Zeeto’s Alexander, he intends to proceed cautiously with Java 9 to mitigate risks.
“Whatever new thing I might build would have to be low-risk. It can’t be a hardened, production, scalable system. I have to trust [Java 9] first,” said Madrid. “There are some principles I would want to follow to be able to observe and control the system. I would set up my acceptance tests, performance tests and I would measure the software and benchmark it against something like 8. If I don’t see improvements and even worse, if I see regressions or unexpected behaviors, I’m going to wait until those are addressed.”
The Apache Maven community has been running some experiments and experiencing some frustrations, which indicative of Java 9’s early days.
According to the Gradle blog, Gradle 3.0 provides initial support for Java 9’s latest Early Access Preview (EAP). Developers can also build and run tests using earlier versions of JDK 9. However, there is no support for modules or JDK 9 specific compile options.
Bottom line, it’s going to take time for JDK 9 to gain traction, but it will get there. Hopefully, the move to the modular architecture won’t be overly painful; however, it will require a lot of patience and hard work on developers’ parts, especially in the early days as things break and behave unexpectedly.
Tools will help ease the pain eventually, as they always do.