Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Mark Reinhold on Java 9 and Beyond

Mark Reinhold on Java 9 and Beyond


Today at EclipseCon, Mark Reinhold presented the keynote "Java 9 and Beyond" which looked at the upcoming features for Java 9 and future plans for the Java ecosystem.

One of the main changes in Java 9 will be the introduction of the Java Module System, under the JEP200 umbrella. This is intended to provide a modularised JDK and correspondingly smaller amounts of code that needs to be loaded when running applications that don't need the whole environment, or in Mark's words "It should not be necessary to depend on CORBA to print 'Hello World'". The work on modularisng both the Java VM source code layout (JEP201) as well as modularising the individual Java components and the run time images (JEP220) will end up with a number of different distinct modules, of which java.base will be the core layer, with others such as java.logging and java.sql (containing both the java.sql and javax.sql packages) that will depend upon it.

Modules themselves can express dependencies between them, but packages are also exported from modules for the use of others. Due to internal implementation details, some packages (such as sun.reflect.* from the java.base module) are made available to friends (like java.logging and java.sql) although these won't be visible to normal Java code. Dependencies are transitive, so code that depends on java.sql will automatically inherit a dependency on java.logging, in the same way that Eclipse bundles using Require-Bundle operate. Security checks with the java.lang.SecurityManager::checkPackageAccess are performed to ensure that the module boundaries are checked at run-time.

These modularisations mean the removal of the ubiquitous rt.jar (Which replaced Java 1.1's and enable the creation of profiles, to reduce the total footprint of the JVM. The compact1 profile – containing the java.base module with the java.lang package and others – clocks in at around 11Mb of size, with compact2 adding RMI and XML (17Mb) and compact3 adding java.naming, and java.sql (30Mb). The full JRE is still available with a buffet option of 55Mb and the JDK extends that to ~150Mb. The modules have also resulted in the removal of the extension classpath and some reorganisation of the lib path (specifically, the movement of the *.properties files from lib/ to a new directory conf/)

One impact to code is the change of the jar: protocol handler for system classes to the new jrt: protocol (Java Run Time). This will allow classes to be loaded from what was rt.jar by specifying the module. So references like jar:file:/path/to/rt.jar!java/lang/Class.class will become instead jrt:/java.base/java.lang.Class.class. These should be implementation details for callers of the ClassLoader.getSystemResource() which has always returned an opaque URL, but code that assumes a relationship to a JAR file or filesystem will be broken. Tools that navigate the rt.jar (such as IDEs like Eclipse and IntelliJ) will instead have to use a different mechanism to navigate modules; a new FileSystem has been registered so that browsing FileSystem.getFileSystem("jrt:/") will allow a path-based access to list out all modules available and their contents.

These modules will be able to be linked into a single runtime using jlink, a new tool in Java 9 to build a custom image that contains only the required dependencies that can be run. The implication was this would be a static linking option to provide a single executable (like Google's Go produces).

Modularisation finally enables the removal of the *.internal.* and sun.* packages. Although code should never have been using these in the first place, the lack of inter package boundaries has resulted in their use inadvertently in codebases. Classes such as sun.misc.BASE64Encoder and sun.misc.BASE64Decoder should be replaced with their standard counterparts in java.util.Base64.Encoder and java.util.Base64.Decoder. A tool jdeps, available in Java 8, will present dependencies of internal classes on existing files, as well as indicating what modules are used in Java 9.

The (possible) Future

Mark Reinhold also discussed about possible future additions to the JVM, such as value classes (structs) and enhanced generics for value types (such as value classes or primitives). These are not scheduled for inclusion in any future, but the thinking and investigating leads to the possibility of inclusion at some point in the future.

A value class is one that represents fixed structure of data, like a class. Unlike a (reference) class however, the implementation allows for the JVM to optimise the data structure directly on the stack, or in arrays, a contiguous memory layout. This improves the access of data structures and importantly improves performance on CPUs which can load contiguous memory in blocks instead of following an array of pointers elsewehre in the heap. An implementation might look like:

value /* final */ class Point {
  int x;
  int y;
  Point(int x, int y) { this.x = x; this.y = y }

Value classes are final by default, so the data structure needs to be fully initialized at creation time. This allows for the JIT optimisation to pass values through to method calls and not to keep copies around where unnecessary. Value classes can have methods and implement interfaces (and potentially subtype other value classes) but they aren't references, so cannot be compared with null. Value classes could be used to implement other primitive-like types, such as int128, Complex or Tuple.

To realise generics with value classes requires some changes; for example, ArrayList<T> has a remove(int index) and a remove(T value) method. Generifying this with int would result in a method clash and cause problems. Whilst creating a new method removeAt(int index) solves the problem, to allow existing types to continue the existing method (for non value types) needs to be exported. A possible approach is to use conditional compilation, which can be implemented using something like a 'where ref T { }' conditional compilation block that exports code for reference types but not for value types. Project Valhalla is investigating how these two concepts might co-exist in the future, but is at the active research stage at present.

Mark Reinhold also briefly mentioned Project Panama, which aims to improve the performance of Java to Native code calling with the Java Foreign Function Interface proposed in JEP191 based upon JRuby's existing JNA and JNR implementations. He concluded the presentation by saying that Java is evolving, and tacking big issues in measured steps – first generics in Java 5, then lambdas in Java 8 and modularity in Java 9 – with a laser-like focus on backwards compatibility so as not to break existing code or consumers.

Rate this Article