JavaOne took place from October 1st to 5th in San Francisco and we were there! This is the first part of our feedback about the main topics: Java 9, Jigsaw - the new Java module system, Java EE 8 and its tranformation to EE4J.
This is the first article of a series and will be followed by others, concerning different topics discussed during this edition such as micro-services, functional and reactive programming, DevOps & Serverless but also more personal feedback.
Java 9 & Jigsaw
2017 was the release year of the sooooo long awaited Java 9 that came with Jigsaw, a totaly new module system but also with many other changes.
Moving Java Forward faster
As explained by Mark Reinhold, Chief Architect of the Java Platform Group at Oracle in the post Moving Java Forward faster he wrote before JavaOne, Oracle is dramatically accelerating the release cycle of Java SE with one release every 6 months.
Java SE release number scheme is also moving from a standard scheme based on incremented numbers to a new time-based scheme:
To make it clear that these are time-based releases, and to make it easy to figure out the release date of any particular release, the version strings of feature releases will be of the form $YEAR.$MONTH. Thus next year’s March release will be 18.3, and the September long-term support release will be 18.9.
Next Java version will then be 18.3 and the next one 18.9. (or maybe not)
This new 6 months release cycle will allow Java to deliver new features in Java as soon as they are ready and only when they are ready. This requires, quoting Mark Reinhold, a new “pipeline of features that we are working on” and that could be included, as soon as they are ready, in the next jdk. This pipeline takes place in the OpenJDK community inside projects such as Panama, Valhalla, Amber or the new Loom, presented by Brian Goetz.
edit: it seems that we could get a Java 10 version after all
Java SE Support
Oracle has also completely revised its policy regarding the support for Java SE itself and the place of OpenJDK. Starting from now, there will no longer be any difference between OracleJDK and OpenJDK!
This announcement was obviously very well received by the community but should not make us forget that it is accompanied by some significant changes regarding the support of OpenJDK & OracleJDK.
Oracle will support and patch only the last version of OpenJDK and you will have to either update your JVMs every 6 months or subscribe to OracleJDK (and pay) to beneficiate from security or performance patches. Indeed, only OracleJDK will provide LTS, not OpenJDK.
A consequence of all of this is that Java 9 is not a LTS release and will be only supported until March 2018. Prepare to upgrade quickly to 18.9 that will be the first LTS release post Java 9 and will mark the end of Oracle JDK 8 public updates. Then, there will be an Oracle LTS release every 3 years.
Jigsaw: Java modules
Jigsaw, the new Java module system was of course the most important and eagerly awaited novelty of Java 9, after repeated postponements.
It is therefore natural that many talks were about the modularization of Java itself, of our own applications and about the progressive transition to modular architectures and the impact on our day to day work. There were even some feedbacks and guidelines from early adopters such as Netflix.
The Jigsaw project, which is now part of Java since Java 9, aims to improve the modularity, efficiency and security of the platform, thus offering the possibility to build more scalable, lighter Java applications with a higher level of safety and security.
The ultimate ambition is to develop a complete ecosystem based on the language and the JVM. Through a modular SDK for building modular applications and using tools that are already almost compatible with this new approach.
More concretely, Jigsaw intends to address the following points:
Getting rid of JAR hell / classpath hell:
The fact that dependencies between packages are not explicitly defined leads to many problems and errors: JAR not found and
NoClassDefFoundError, version conflicts and shadowing of classes and packages… not to mention transitive dependencies. Class loading mechanisms have contributed to build a complex system, poorly effective and hard to understand.
Stronger encapsulation & better security accross packages:
Mechanisms of encapsulation accross packages are weak and, by means of the reflection API, they are very easy to bypass.
Better performances & optimized weight:
The linear scanning of the classpath but also the “all-in-one” approach of the JDK led to poor startup performances and to an excessive application weight.
The first step has been to work on the modularization of the JDK itself.
It has been broken down into multiple modules and each module explicitely define its dependencies to other modules … until
The fact that this new module graph defines the different components of the JDK in the form of an explicit dependency tree makes loading classes from the classpath - which has become modulepath much more efficient in localization of classes.
The new notion of layers allows to deal with class loader hierarchy in a much more intuitive manner. A minimal boot layer is now created by the JVM and results in a much better startup performance. Additional layers can be created and stacked on the top of the boot layer.
The division into modules allows to finally get rid of the monolith
rt.jar and its 53Mo! Deprecated Java EE modules (such as
java.transaction) have been deprectated for removal and must be added via
jlink --add-modules if needed.
This new tool, jlink allows you to finely choose the modules and dependencies to include in your distribution (including those of the SDK) and to link them together. It greatly contributes to reduce and control the size of your deployments. jlink, via the notion of link time also allows an advanced control of linking, with the possibility to choose between static linking and dynamic linking.
$ jlink --module-path <modulepath> --add-modules <modules> --limit-modules <modules> --output <path>
All this helps to offer a much more lighter JDK to embed in our applications.
jdeps, the Java Dependency Analysis Tool, is a new command line tool that analyzes the dependencies between classes and offers a great help in the modularization process.
A module remains a regular JAR file with a
module-info.class file at its root containing its name and its dependencies.
As usual, naming is essential and hard and the strategy will depend on the nature of the module: application or library.
Dependencies are expressed using
requires transitive and
requires static allow declaring direct, transitive or even static dependencies. Static dependencies make possible expression of optional dependencies, declaring that a dependency is mandatory at compile time but not necessarily available at run time: the application will be able to start without that dependency.
public types of a module are no more visible outside of itself. To make them visible by other modules, you’ll have to explicitely export packages with the
exports keyword. Note that you can explicitely restrain the visibility to some modules using
exports <package> to <module>.
To enforce security, you cannot anymore use reflection without permissions on private fields. No more
setAccessible(true) ;-)! Required modules have to explicitely allow it using the
opens keyword on a given package to allow its usage or use
open <module-name> when declaring the module to allow usage for the entire module.
opens have considerably increased the safety and encapsulation of the modules, at compile time and at runtime. And deep reflection is not a free lunch anymore.
ServiceLoader mechanism, that exists since Java 6 but was never really exploited, has been revamped. Indeed, using
exports enforce encapsulation but in case of multiple possible implementations, you cannot rely only on interfaces and still have to create concrete instances yourself which leads to excessive coupling. Services claim to address this concern by registering implementations on one side and relying on the
ServiceLocator on the other to retreive concrete objects.
A module can declare a service by using
provides <interface> with <implementation>, then becoming a Service provider. To use a service provided by another module, a Service consumer module has to declare
uses <interface> inside its
module-info.jar, in addition to requiring the module itself.
Migration path & backward compatibility
To facilitate the migration and its adoption, Jigsaw is announced as taking into consideration the backward compatibility of existing applications, if they complied with previous standards.
Several mechanisms are available for this purpose:
class-path& unnamed modules: Classpath did not completely disappear and you can simply load your legacy pre-Java 9 libraries using the command line and the
--class-pathoption. All these libs and packages will then be added to a unique unnamed module. All packages inside this module will have full access to other internal packages, to any public exported package of the
module-pathand any module from the
module-pathwill have access to public classes from packages of the unnamed module. But it seems that this is is a short-term situation to facilitate migration and strong encapsulation is the target for future OpenJDK releases. It means that that classes from the unnamed module (in fact the classpath) will not export anything.
To go one step further, you can start considering you legacy JARs as quite regular modules inside the
module-path. Each JAR will then be considered as an automatic module real module which name will be deducted from the JAR file name without version, extension, etc. If needed, the automatic name of your JAR file can be customized with
--add-opensallow to keep deprecated modules and to authorize again Illegal access to JDK internals.
Tools and frameworks have already done a great job in supporting Java 9 and modules and most of them are already provinding a good support of these new features and architecture
That was theory! In practice, it will still lead to many challenges:
As mentionned above, naming of modules will be non trivial with strong unicity constraints and requirements. Automatic modules without explicit
Automatic-Module-Name could lead to ambiguous situations, conflicts and errors. This point may be particularly painful during the transition period, until the entire ecosystem has migrated to the modules.
Jigsaw also considers the versionning is not his area of responsibility and leaves this problem to build tools. It does not offer any mechanism to manage or even declare the version of modules.
This point seems particularly problematic to me and I confess to be rather skeptical about the possibility of concretely managing direct and transitive dependencies of an entire application without structurally taking into account versions and possible collisions.
But becoming modular is not just a matter of backward compatibility. We will have to rethink part of our architectures and significantly refactor our applications to take into account these new patterns. No more overloading of packages, for example:
Deciding on the granularity of the modules will also be very challenging, between small modules promoting composability and reusability and all-in-one modules that will be much easier to implement. One answer might be not to choose and to use aggregator modules requiring all necessary dependencies to multiple small modules.
Another important drawback of the modularization is code testing. A few sessions were about build tools and keeping the tests working. The main problem is that test code can not access main source code if it is compiled in two modules. Cédric Champeau provided some insights on how Gradle tackles the problem and it is merely a hack today (hack java compiler task to give it the classpath as module path). Even though, Gradle gives a workaround to this problem, the question remains on the plugins and extensions used by build tools. There is a huge number of plugins not yet compatible with Java 9, breaking builds so there is still lots of work before having projects building correctly on Java 9.
The arrival of Jigsaw is certainly an important step in the modernization of the platform but does not necessarily convince everyone on all the aspects it intends to deal with.
Modernization of the classpath, class loading, modularization of the JDK and the resulting improvements in performance and efficiency are certainly important steps.
Given the increase in complexity caused by modules, however, this was not enough to significantly reduce the overall complexity of these mechanisms, and the absence of versioning in dependency management is still an important source of questioning.
After so many years of waiting, we are legitimate to wonder if this proposal addresses all the necessary problems and will be able to obtain the community’s agreement. Some reservations were publicly expressed by two members of the JCP: IBM and RedHat.
The next few months will be critical and it will be interesting to observe the degree of adoption within the entire ecosystem and community involvement in the migration of tools, applications, frameworks and libraries.
- Modules in One Lesson by Mark Reinhold
- Designing for Modularity with Java 9 by Sander Mak and Paul Bakker (slides)
- Modular Development with JDK 9 by Alex Buckley (slides)
- Migrating to modules by Mark Reinhold
- Modules and Services by Alex Buckley (slides)
- Migrating to Java 9 modules by Paul Bakker
- Building and Testinf Java 9 applications with Gradle by Cédric Champeau
Other Java 9 features
With Jigsaw, modularity is obviously the biggest change in Java 9, but this new release came with many other improvements and features regarding tooling, performances, APIs, security or even language.
jshell: a REPL (Read Eval Print Loop) for Java: Java finally has a command line and its name is jshell (or JEP 222).
Like any command line tool, jshell provides Tab completion, retrieves information from javadoc, etc. It can be used as a binary tool but also via its API.
But, as pointed out by Simon Mapple and Oleg Shelajev in their very funny talk The Good Cop/Bad Cop Guide to Java 9, jshell comes with new behaviors, quite unusual in the Java world:
You can download the JShell user guide
JavaDoc.Next - a new generation of JavaDoc: Rejuvenation cure for JavaDoc with JavaDoc.Next with HTML5 support and doclint support, a simplified Doclet API and a quite powerfull JavaDoc search box by default!
Compiling: With Multi release jar files (JEP 238) you can build a single jar file containing multiple Java-release-specific versions of a class/resource file, with Compile for Older Platform Versions (JEP 247) you can compile for older releases.
Amendements to project Coin (JEP 213): Such as
@SafeVargson private instance methods, diamond with anonymous classes or effectively final variables & try-with-resources:
Miscelaneous language changes: Allowing private interface methods, better management of deprecation and deprecation warning with Elide Deprecation Warnings on Import Statements and Enhanced Deprecation
Strings and string concatenation: Replacement of String-internal
charrepresentation with a
bytearray plus encoding field thanks to Compact Strings (JEP 254), optimization of String concatenation with Indify String Concatenation (JEP 280)
Initializing collections with
ofmethod: Convenience Factory Methods for Collections (JEP 269) is offering a far more elegant solution for initializing collections:
// Java 8 Set<String> set = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("a", "b", "c"))); // Java 9 Set<String> set = Set.of("a", "b", "c");
New methods in java.util.Objects:
Not to mention security enhancements coming with Java 9 and presented by Sean Mullan in his talk “Making the JDK more secure” (slides).
We are not going to go into detail here on this topic but you’ll find everything in this talk and on this dedicated guide to Secure coding guidelines for Java SE, updated for Java 9.
A new Cryptographic Roadmap has also been published.
JVM & Performances
Many improvements have been made on the JVM regarding performances, garbage collector, vectorization, etc. We are not going to list them all here, but if you are interested, you should take a look to Mikael Vidstedt and Sandhya Viswanathan’s talk JDK 9 Hidden Gems (slides).
- Oracle Keynote about Java 9 by Mark Reinhold
- The Good Cop/Bad Cop Guide to Java 9 by Simon Maple and Oleg Shelajev with slides
- JDK 9 Language, Tooling, and Library Features by Joseph D. Darcy with slides
- 55 new features in JDK 9 by Simon Ritter
- JDK 9 Hidden Gems by Mikael Vidstedt and Sandhya Viswanathan with slides
- JShell: An Interactive Shell for the Java Platform by Robert Field
- Exploring Java 9 with REPL by Miro Cupak with slides
- The G1 GC in JDK 9 by Erik Helin with slides
Java EE to EE4J
2017 has not only been a pivotal year for Java SE, it is also a year of radical transformation for Java EE. As announced prior to JavaOne, Oracle is “opening up” Java EE to the community.
Java EE is already developed in open source so it is not about opening the code itself but about transferring the governance of Java EE to the community.
… the process is not seen as being agile, flexible or open enough, particularly when compared to other open source communities. We’d like to do better.
In practice, it is the Eclipse foundation that will have the heavy task of hosting the Java EE galaxy and taking charge of its governance with Redhat, IBM, Tomitribe, etc. as the main actors. Future versions of Java EE, with EE4J as new name, will be licenced under Eclipse Public License 2.0.
Oracle assures that it will continue to play a major role in the evolution of Java EE without going into further detail and many questions remain unresolved regarding Oracle’s participation in JCP, TCKs, etc.
We will continue to participate in the future evolution of Java EE technologies. But we believe a more open process, that is not dependent on a single vendor as platform lead, will encourage greater participation and innovation, and will be in best interests of the community.
The announcement was generally received positively by the community and its major actors but caused a lot of ink and saliva to flow and naturally gave rise to many debates and talks at JavaOne. With, in particular, two panels:
- Opening Up Java EE: Panel Discussion with Oracle, IBM, Red Hat, and the Eclipse Foundation with Mark Little, Will Lyons, John Clingan, Ian Robinson, David Blevins and Mike Milinkovich
- Powerful Lessons from Top Java EE Experts with Adam Bien, Ed Burns, Reza Rahman, Antoine Durand, Steve Millidge, Edson Yanaga, David Heffelfinger, Ruslan Synytsky, Ivar Grimstad, Kevin Sutter and Bruno Souza
The main message was very optimistic: “The future of Java EE is full of promise and it’s in your hands! Participate, get involved! Contibute to the specs, contribute to the code”
Naming was one of the hard points and made a lot of noise. As usual with Oracle, there were many legal constraints on the choice of name and it was not possible, for example, to keep a name starting with Java. The name chosen for the project is officialy EE4J but it is not certain that it will remain as a brand name.
There is already very heated discussions to obtain the permission from Oracle to keep package names starting with
javax.* We must admit that it would not be very intuitive to have interfaces in
These panels also took the opportunity to appeal to all companies using Java EE by inviting them to seize this opportunity and to dedicate teams to contribute to the specification and development of future versions.
Few answers, finally, after all these debates and still many open questions:
- Will an open and collaborative community be able to provide sufficient leadership?
- Will the key players in this community be able to agree on a shared leadership?
- How big will Oracle’s involvement in the future of Java EE be?
- What will be the final name?
We are not particularly Java EE guys here but we will follow carefully the next months that should be critical for the future of Java EE.
Java EE 8
Again, we are not particularily Java EE guys and we are not going to detail all the content of Java EE 8 here.
But we can quote:
- New projects:
- JSON-B: A new JSON Binding API for a much more easy conversion between Java objects from/to JSON messages. The API seems quite straightforward to use (
toJsonmethods…) and allows the implementation of a custom mapping via annotations such as
- The new Security API whose main objective is to significantly improve portability accross servlet containers from a security management point of view.
SecurityContextwill help to address these concerns.
- JSON-B: A new JSON Binding API for a much more easy conversion between Java objects from/to JSON messages. The API seems quite straightforward to use (
- Major updates for:
- Minor updates for:
The two talks below will give you the big picture:
- Java EE 8: What’s New in the Java EE 8 Release by Linda DeMichiel
- What’s New in Java EE 8? An Overview by David Heffelfinger and Michael Nascimento Santos
And here is a list of more JavaOne talks about Java EE and some specific parts of the Java EE 8 release:
- Java EE 8: What’s New on the JSON Front by David Delabassee
- JSR 375: New Security APIs for Java EE by Ivar Grimstad
- Servlet 4 0: A New Twist on an Old Favorite by Ed Burns and Shing wai Chan (slides)
- Keeping Your Data Sane with Bean Validation 2.0 by Gunnar Morling
- Discover CDI 2 0 in Live Coding by Antoine Sabot-Durand
- What’s New in JAX-RS 2.1? by David Delabassee
- JAX-RS and CDI Bike the (Reactive) Bridge by José Paumard and David Delabassee
- Contemporary Java Web Applications with JSF 2.3 by Ed Burns (slides)
2017 was thus a year full of changes for Java. On the JDK side, many evolutions are still expected in the ecosystem and in the Java community because of the transition to the new modules system and because of the new release rythm which is much more intense. On the Java EE side, it is an even more radical change which is coming. Let’s bet that the next few months and years will be rich in evolutions and transformations, which is, after all, a good thing for the platform as a whole.
But, obviously, many other topics were also discussed during this edition 2017: micro-services, functional programming, DevOps, serverless, etc. We will talk about it in new articles to come. Stay tuned!