© Alexandru Jecan  2017

Alexandru Jecan, Java 9 Modularity Revealed, https://doi.org/10.1007/978-1-4842-2713-8_5

5. Modular Runtime Images

Alexandru Jecan

(1)Munich, Germany

In this chapter we’ll look at the structure of the new modular runtime image introduced in Java 9, which brings an important benefit in terms of improved performance and maintainability. On the other hand, the new format of the runtime image doesn’t necessarily result in preserving the exactly same functionality of all the existing APIs.

Note

This chapter is an informational one that describes the format of the modular runtime images introduced in JDK 9.

Modular Runtime Images

Chapter 3 showed how the source code in the JDK was restructured around modules. In this chapter we’ll talk about the new modular runtime image that was implemented in the Java Enhancement Proposal 220. This JEP modified the structure of the JDK and JRE as a consequence of the introduction of modules. It also defines the layout of the modular runtime image.

The introduction of modules in Java 9 caused an important change in the structure of the JDK and the JRE. As a result, a new runtime format was introduced. The minimum possible runtime that we can have in Java 9 would consist only of the module java.base. A JDK 9 image can be accessed not only by tools that are running on Java 9, but also by tools running on Java 8, for example.

Note

For accessing classes and resources in the JDK and JRE, a helper interface has been introduced in Java 9.

Another important change, not directly related to modules but more related to the JDK, is the replacement of the rt.jar file and the tools.jar file with the new runtime image.

Note

Java 9 doesn’t remove the JAR files and doesn’t prohibit them. JAR files continue to work in Java 9.

Because JAR files can cause many problems, the intention of the JCP team was to stop using them inside the JDK and the JRE as much as possible.

The Runtime Image Prior to Java 9

This section covers the structure of the runtime image prior to Java version 9. We already talked about it in Chapter 2, but now we’ll get into more details. Before Java 9, the JDK build provided us with two types of runtime images: a Java Runtime Environment (JRE) image and a Java Development Kit (JDK) image.

The JRE Image Prior to Java 9

A Java Runtime Environment was a complete implementation of the Java SE Platform. A JRE image was composed of two directories: bin and lib.

The bin directory contained the java command for launching the runtime system and also executable binaries, like javacp, java-rmi, javaw, javaws, keytool, pack200, rmid, rmiregistry, and servertool.

The lib directory was larger than the bin directory and contained .properties and .policy files. The ext directory was placed inside the lib directory and contained JAR files like nashorn.jar, sunec.jar, zipfs.jar, and others. The most important thing to mention is that inside the lib directory we could find the rt.jar file. The lib directory comprised the runtime system's dynamically-linked native libraries on the Mac OS and Linux operating systems.

The JDK Image Prior to Java 9

On the other hand, prior to Java 9, a JDK image enclosed a JRE. It had a copy of the JRE in its jre subdirectory. A JDK image contained many directories, but the most important three of them were the lib, the bin, and the include directories.

Note

A JDK image contained libraries and development tools.

The lib directory consisted of JAR files comprising the implementations of the JDK's tools. The tools.jar file, which included the classes that composed the javac compiler, was located into this lib directory. The bin directory had command-line debugging and development tools like javac, javadoc, and jconsole. The include directory contained C and C++ header files for use in compiling native code that interfaces directly with the runtime system.

Why a New Format for the Runtime Images?

According to Open JDK, there are various reasons why a new format is required for the runtime images. First of all, the new runtime format is more powerful than the old JAR format. Second, the new runtime format can be easily enhanced to hold precompiled native code for Java classes or precomputed JVM data structures. Third, the new runtime format can store class and resource files from application modules, JDK modules, and library modules.

The most important reason behind the decision to revamp the JDK and the JRE is stated by OpenJDK on their website: “to draw a clear distinction between files that developers, deployers, and end-users can rely upon and, when appropriate, modify, in contrast to files that are internal to the implementation and subject to change without notice.”

OpenJDK lists three more reasons:

  • “to provide supported ways to perform common operations that today can only be done by inspecting the internal structure of a runtime image such as, e.g., enumerating all of the classes present in an image”

  • “to enable the selective de-privileging of JDK classes that today are granted all security permissions but do not actually require those permissions”

  • “to preserve the existing behavior of well-behaved applications, i.e., applications that do not depend upon internal aspects of JRE and JDK runtime images”

The Runtime Image in Java 9

This section describes the structure of the new runtime image introduced in Java 9.

Identical Structure of the JDK and JRE

The JRE and the JDK have the same structure in Java 9. This is different from older versions of Java where, as described earlier, there was a clear distinction between the JDK and the JRE. A JDK image is simply a runtime image that contains the development tools from the JDK.

Configuration files that were once located in the lib directory are now located inside the conf directory. These are files we can edit. The files in the lib directory are implementation details of the runtime system.

Note

The files from the lib directory should not be modified.

The Structure of the New Runtime Image

Figure 5-1 shows the new structure of the runtime image in Java 9.

A431534_1_En_5_Fig1_HTML.jpg
Figure 5-1. The structure of the runtime image in Java 9

Let’s see what kind of directories the new modular runtime image contains:

  • The bin directory incorporates command-line launchers represented by the modules that are linked into the image. Some of the most important command-line launchers are java, javac, javadoc, javah, javap, jcmd, jconsole, jdeps, jimage, jlink, jmod, jshell, and jstat. We are not going to describe all of them here. You can check the bin directory of the JDK 9 build.

  • The lib directory consists of the runtime system’s dynamically-linked native libraries.

  • The conf directory contains files that can be edited. Among them are .properties files and .policy files.

  • The jmods directory contains all the JMOD files.

  • The legal directory contains the copyright files.

The root directory of a modular runtime image contains copyright, readme, and release files.

The release File

The structure of the release file contains information about the modules, OS version, source, operating system arch, operating system name, Java version, and the full Java version:

IMPLEMENTOR="Oracle Corporation"

JAVA_VERSION="9"

MODULES="java.base java.datatransfer java.logging java.activation java.compiler java.rmi java.transaction java.xml java.prefs java.desktop java.security.sasl java.naming jdk.unsupported java.corba java.instrument java.jnlp java.management java.management.rmi java.scripting java.xml.ws.annotation java.xml.crypto java.security.jgss java.sql java.sql.rowset java.se jdk.httpserver java.xml.bind java.xml.ws java.se.ee java.smartcardio javafx.base jdk.jsobject javafx.graphics javafx.controls jdk.deploy jdk.javaws jdk.plugin javafx.deploy javafx.fxml javafx.media javafx.swing jdk.xml.dom javafx.web jdk.accessibility jdk.internal.jvmstat jdk.attach jdk.charsets jdk.compiler jdk.crypto.ec jdk.crypto.cryptoki jdk.crypto.mscapi jdk.deploy.controlpanel jdk.dynalink jdk.internal.ed jdk.editpad jdk.hotspot.agent jdk.incubator.httpclient jdk.internal.le jdk.internal.opt jdk.internal.vm.ci jdk.jartool jdk.javadoc jdk.jcmd jdk.management.agent jdk.management jdk.jconsole jdk.jdeps jdk.jdwp.agent jdk.jdi jdk.jfr jdk.jlink jdk.jshell jdk.jstatd jdk.localedata jdk.naming.dns jdk.naming.rmi jdk.net jdk.pack jdk.packager.services jdk.packager jdk.plugin.dom jdk.plugin.server jdk.security.jgss jdk.policytool jdk.rmic jdk.scripting.nashorn jdk.scripting.nashorn.shell jdk.sctp jdk.security.auth jdk.snmp jdk.xml.bind jdk.xml.ws jdk.zipfs oracle.desktop oracle.net"

OS_ARCH="x86_64"

OS_NAME="Windows"

SOURCE=".:a4371edb589c+ closed:3b9bef864bcf corba:c72e9d3823f0 deploy:d12d0210bc37 hotspot:1ca8f038fceb hotspot/make/closed:0b47834a0294 hotspot/src/closed:f5870a8748c9 hotspot/test/closed:2a88d69ed789 install:6549b99d10f0 jaxp:332ad9f92632 jaxws:b44a721aee3d jdk:80acf577b7d0 jdk/make/closed:1793d3af1ed9 jdk/src/closed:8e4a66cb15a6 jdk/test/closed:860a0f54d259 langtools:2f01728210c1 nashorn:aa7404e062b9 sponsors:d751e23bea1e"

The next section discusses the rt.jar, tools.jar, and dt.jar files that were removed in JDK 9.

Removed Files

Rt.jar Removed

The rt.jar file comprised the entire compiled class files that formed the JRE. These represented all the compiled classes from the Core Java API, including the sun and com packages. rt.jar used to be located inside the lib folder of the JRE. In Java 8, the rt.jar file weighed approximatively 52 MB. In all Java versions prior to version 9, it was absolutely mandatory to include the rt.jar file into the class path in order to be able to access the core Java libaries. But the rt.jar file has been completely removed in Java 9. It doesn’t exist anymore among the files that make up the JDK 9.

Tools, compilers, and integrated development environments (IDEs) using rt.jar are affected by the removal of the rt.jar file. They have to be adjusted by their authors in order to continue to work properly in Java 9.

According to the specification of JEP 220, “the class and resources files previously stored in lib/rt.jar, lib/tools.jar and lib/dt.jar, and various other internal JAR files will now be stored in a more efficient format in implementation specific files in the lib directory.”

In JDK 9, the rt.jar file was replaced by the new runtime.

Tools.jar and dt.jar Removed

Before JDK 9, the tools.jar file was used by the JDK and was located in the lib directory of the JDK version 8 or lower. It contained classes used by javac and also support for tools like javah, javap, jdeps, javadoc, and more. The dt.jar file was also located inside the lib directory and contained Swing classes.

Note

Both tools.jar and dt.jar have been removed in Java 9.

In Java 9, resources and class files that were formerly located inside the tools.jar file are visible via the bootstrap or application class loaders in a JDK image. Similarly, resource and class files that were formerly located inside the dt.jar file are visible via the bootstrap class loader in Java 9.

New URI Scheme

A new URI scheme was introduced in JDK 9. To demonstrate the new URI scheme, we’ll first show a simple example. In this example, we use the getSystemResource() method of the ClassLoader class to find a URL resource of the class String from the search path used to load classes. The resource will be located through the system class loader.

In Listing 5-1 the getSystemResource() method retrieves the URL resource of the class java.lang.String.

Listing 5-1. The Main Class of Module com.apress.getSystemResource
// Main.java (module com.apress.getSystemResource)
package com.apress.getSystemResource;
import java.net.URL;


public class Main {
        public static void main(String[] args) {
           URL url = ClassLoader.getSystemResource(“java/lang/String.class”);
           System.out.println(url);
        }
}

Listing 5-2 defines the module descriptor of the module com.apress.getSystemResource.

Listing 5-2. The module-info.java File of Module com.apress.getSystemResource
module com.apress.getSystemResource {

}

We run the previous module and see the resulting URL printed in the console:

jrt:/java.base/java/lang/String.class

Let’s now run the same example on Java 8. The resulting URL in this case would be as follows:

jar:file:/C:/Program%20Files/Java/jdk1.8.0_101/jre/lib/rt.jar!/java/lang/String.class
Note

You can find the source code for this example in the directory /ch05/getSystemResource.

We observe that the output is completely different between Java 8 and Java 9. In Java 8, the URL has the form of a JAR file and the String.class is located inside the rt.jar file. It’s not possible to have the same output in Java 9 because Java 9 doesn’t have an rt.jar file.

To solve this problem, Java 9 introduces a new URL scheme called jrt that provides access to the content of the runtime image. The term jrt is derived from java runtime. According to Open JDK, the jrt URL scheme “is used for naming the modules, classes, and resources stored in a runtime image without revealing the internal structure or format of the image.”

Note

A jrt URL can have a total of four distinct forms.

Figure 5-2 shows the simplest structure of the jrt URL.

A431534_1_En_5_Fig2_HTML.gif
Figure 5-2. Simplest structure of the jrt URL

This jrt URL, which doesn’t specify anything else except the jrt:/, specifies all the files that exist in the current runtime image. But we can have more representations of the jrt URL. Figure 5-3 shows another form of the jrt URL that specifies only the module name.

A431534_1_En_5_Fig3_HTML.gif
Figure 5-3. Structure of the jrt URL with module

In this case, the jrt URL specifies all the files from the module that was specified.

Figure 5-4 represents another form of the jrt URL that contains only the path, but no module name.

A431534_1_En_5_Fig4_HTML.gif
Figure 5-4. Structure of the jrt URL with path

In this case, the path represents a resource file or a class from the current runtime image. The path is not bound to a specific module.

Figure 5-5 shows the full structure of the jrt URL, specifying both a module and a path.

A431534_1_En_5_Fig5_HTML.gif
Figure 5-5. Full structure of the jrt URL

The full structure of the jrt URL refers to a specific resource file within the given module. The jrt scheme also allows retrieving the contents of platform modules.

Now that we’ve learned about the new URI scheme, let’s move on and talk about the compatibility problems that can arise due to all these modifications.

Compatibility

As mentioned, important compatibility problems can eventually occur in Java 9 for some existing applications due to the new structure of the JDK. Compatibility issues will appear in Java 9 for applications that strictly depend on the internal structure of the JDK. Because the JDK doesn’t contain the jre subdirectory anymore, every piece of code that makes use of this subdirectory will stop working as expected.

Moreover, in Java 9 the system properties java.endorsed.dirs and java.ext.dirs have been removed. This means applications that rely on these two system properties won’t work correctly in Java 9.

The removal of rt.jar, tools.jar, and dt.jar files also has a negative impact on applications that rely on them.

Another compatibility problem will arise in Java 9 for source code that expects JAR URLs for naming class and resource files inside the runtime image. As mentioned, the jar URLs have been replaced with jrt URLs.

Another topic that needs some attention is related to class loaders. Table 5-1 shows the class loaders that were changed in Java 9, together with the new class loaders and the corresponding packages. Chapter 10 covers the class loaders in more detail .

Table 5-1. The Class Loaders Changes

Package

Old Class Loader

New Class Loader

sun.tracing.dtrace

boot

application

sun.tools.jar

boot

application

sun.security.tools.policytool

boot

application

com.sun.tracing

boot

application

com.sun.tools.script

application

boot

com.sun.tools.corba.se.idl

application

boot

com.sun.jndi.url.dns

boot

extension

com.sun.jndi.dns

boot

extension

com.sun.crypto

extension

boot

As a result, source code that that depends on the class loaders of the packages listed here may not work properly in Java 9.

Summary

This chapter covered the new modular runtime images introduced in Java 9 and the reasons behind the decision to introduce them. It compared the runtime image we had before Java 9 with the one in Java 9.

We explained in detail what every folder of the new runtime image contains and showed the content of the release file. We talked about the removal of the rt.jar, tools.jar, and dt.jar files and emphasized the consequences for existing applications. We continued by presenting the new URI scheme, which consists of a jrt URL instead of a jar URL.

The chapter conculded by summarizing the compatibility problems that may occur due to the changes implemented in JEP 220. For more information on the topics discussed in this chapter, consult the documentation of JEP 220 at http://openjdk.java.net/jeps/220 .

Chapter 6 shows how to decouple modules using services.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.44.229