■ IntroduCtIon
xxiii
Accessibility is an important part of the entire ecosystem and is covered throughout this book. The integral
concept regarding the manner in which accessibility is achieved fundamentally changes in Java 9. The public
access identifier that we all know no longer means accessible everywhere and to anyone. Supplementary
accessibility levels have been added in JDK 9 that extend the existing accessibility mechanism by defining
accessibility at the module level. Concepts like direct and implied readability, prerequisites for defining
accessibility, are also outlined in this book. You’ll see how accessibility is imposed by the compiler, by the
virtual machine, or by using core reflection.
We’ll look at the new concept of modular JAR files and the great advantage it brings: the possibility
of compiling a library with JDK 9+, using it on the module path for JDK 9+, and compiling it with JDK8 or
earlier and using it on the class path. Because the class path can still be used, the migration of libraries
to JDK 9 is smooth. Even if the libraries contain a module descriptor and are to be treated as “modules,”
they will still work on previous versions of JDK 9 because their module descriptor won’t be taken into
consideration on the class path. By using modular JARs, developers have the freedom to decide whether they
want to switch to the module platform or not.
We’ll highlight the distinctions between regular and modular JARs with some examples and describe
the new format for files introduced in Java 9, called JMOD, which is very similar to the format of JAR files.
We’ll go over the new JMOD tool and describe its use in detail.
The compilation of multiple modules using the --module-source-path option is illustrated with some
explanatory examples. We’ll also describe the enhancements added to the jar tool and show how to use it to
package everything as a modular JAR or as a JMOD file.
We’ll see how to run the compiled classes and the module-info.class using the java launcher. New
options like --module-path and -m, introduced in JDK9, are covered thoroughly. When attempting to run an
application using the -m option, which tells the launcher where the main module is, a resolution is triggered.
We’ll describe in detail all the steps involved when running a Java modular application, including resolution
triggering and generation of the module graph. We’ll also look at special cases like when a module is missing
and the startup fails, and we’ll present some workarounds for this, such as using the newly introduced java
launcher option --show-module-resolution.
We’ll also put modular JARs on the class path and see how to successfully run them. This is very
important: We’ll explain how to mix the class path and the module path when running with the java
launcher. For this, we’ll take advantage of the newly introduced --add-modules command-line option.
Chapter 3 describes the JEP 200, called the Modular JDK. This is the JEP that splits the JDK into a set of
modules. We’ll consider the new structure of the JDK together with its modules. We’ll talk about platform
modules and show the module graph that represents the new modular structure of the JDK. We’ll examine
the graph, show how modules depend on each other, and learn how to list all the modules from the system
using the --list-modules command-line option. We’ll also explain the notions of standard module and
non-standard module.
It’s beyond the scope of this book to go through every module in detail. You can find a comprehensive
list of all the existing modules on the Open JDK website at http://cr.openjdk.java.net/~mr/jigsaw/ea/
module-summary.html.
The JEP 260, Encapsulate most internal APIs, is also covered in this book. In order to manage
incompatibilities, all non-critical internal APIs were encapsulated by default. Besides that, all critical internal
APIs for which supported replacements exist in JDK 8 were encapsulated. Other critical internal APIs weren’t
encapsulated. Since they were deprecated in JDK 9, a workaround via a command-line flag is provided.
A linker and a new phase called link-time were introduced in Java 9. This phase is optional and is
executed after the compile-time but before the runtime. It basically assembles the modules in order to form
a runtime image. Runtime images allow us to create custom JDKs that contain only the minimum number of
modules necessary to run our application. The minimum possible runtime would contain a single module,
the java.base module. Runtime images allow us to scale down the JDK or to scale it up based on our needs.
They’re a replacement of the runtime rt.jar.