Official Documentation: https://docs.oracle.com/javase/9/index.html
Regarding the new features of Java 9, official text: https://docs.oracle.com/javase/9/whatsnew/toc.htm
This is just a list, and specific technical details need to be explored based on the official documentation.
Modular System
The modularization of Java 9 comes from an independent open-source project called Jigsaw.
Project Official Website: http://openjdk.java.net/projects/jigsaw/
Why Use Modularization
Java developers know that when developing applications in Java, they often encounter a problem known as Jar hell, similar to DLL hell in Windows.
For example, we start a relatively small application but depend on many jars, as shown in the image below:
Excerpt from: Mark Reinhold’s talk https://www.youtube.com/watch?v=l1s7R85GF1A
This is quite common. Although you can use “java -Djava.ext.dirs=lib xxx” to make the command line smaller, it is undeniable that the classpath is still very long. By the way, using extdirs is not allowed in Java 9.
On the other hand, the JDK itself has many APIs:
For some small devices, it is too large.
Hello World
Let’s start with a Hello World example. Before that, you need to check your Java version:
If it is not Java 9, but rather 1.8 or 1.7, then you are not welcome.
Create Main Class
First, create a Java class named Demo.
Save the file as: src/com/pollyduan/modular/Demo.java
Compile:
Package Jar and Execute
The –class-path switch can be abbreviated:
Of course, we can specify the main class for the jar to simplify execution:
We need to add the above line in MANIFEST.MF to run directly:
Create Module
src/module-info.java
We wrote an empty module named hello.
Compile Module
Let’s decompile and take a look:
Why did we write an empty module, but the decompilation added a line? Don’t worry about it for now; it will be explained later.
Package Module
Run Module
This is different from executing a traditional jar; here, we do not need a classpath but rather a module-path.
The command line can also be abbreviated as:
Can a module add a Main-Class? Java 9’s jar provides a create switch, which allows you to specify the main class for the module when packaging:
Running the module again will make the command line simpler.
Design Goals of Jigsaw
Make it easier for developers to build and maintain large libraries or applications;
Improve the security and maintainability of the Java SE platform and JDK implementation;
Enhance application performance;
Make applications smaller for easier deployment on smaller computing units and tight cloud deployment systems.
What are Modules
To address these issues, the JDK encapsulates a layer above packages.
So what exactly is a module?
A module is a container for packages. A module only needs to export the packages it depends on.
Create a Module
Declare a Module
cat module-info.java
Similar to package-info.java, it is also saved in a separate Java file named module-info.java.
Create Classes to be Exported
For now, the content of the class is not important; you can write an empty class first. Here is just the directory structure:
Compile Module
Package Module
Check the jar structure:
Reference Module
Now that we have the module com.foo.bar-1.0.jar, we can use the requires keyword to reference this module when defining other modules.
Built-in Modules
The native packages of the JDK are merged into built-in modules, such as the java.base module:
All applications will default to depend on java.base, just like we used to not explicitly “import java.lang.*;”.
This verifies why, in the previous Hello World example, the decompiled module file had an additional line: “requires java.base;”.
The following com.foo.app module does not need to explicitly import java.base:
If at this point com.foo.bar adds a reference to the com.foo.baz module.
Then we know that com.foo.bar also implicitly includes java.base.
Similarly, the com.foo.baz module also implicitly references java.base:
Reliable Configuration
As we delve deeper, we know that java.sql references a large number of other APIs, so the following diagram is not difficult to understand.
The current module structure is called readable modules, providing reliable configuration.
If a non-existent module is referenced, like with jars, you will also trigger an xx not found error.
At compile time:
At runtime:
Accessible Types
If the referenced module does not export a certain class, then it is inaccessible, which is called strong encapsulation.
For example, if there is an internal class BetaImpl in the com.foo.bar module:
Then in the actively referenced module com.foo.app, it is used as follows:
At compile time, an exception will be triggered:
This means: BetaImpl is inaccessible because the package com.foo.bar.beta.internal is not exported.
Similarly, even if you successfully edit using the exported version, if at runtime you reference the non-exported version of the module:
View Built-in Modules
View more built-in modules:
Advanced Hello World
Based on Hello World, add a module dependency.
First, let’s review the directory structure of Hello World:
Add a Module Service, where the service directory is at the same level as the module directory.
Create Service Class
service/src/com/pollyduan/service/HelloService.java
Declare Service Module
service/src/module-info.java
Compile Service Module
Package Service Module
Modify Hello World Module
module/src/module-info.java
Modify Hello World Main Class to Use Method from Service
module/src/com/pollyduan/modular/Demo.java
Recompile and Package Hello World
That’s it for the packaging.
Tools Related to Modules
We won’t discuss the existing javac/javap, but here are a few new ones. For more, refer to: https://docs.oracle.com/javase/9/tools/tools-and-command-reference.htm#JSWOR-GUID-55DE52DF-5774-4AAB-B334-E026FBAE6F34
jlink
A module packaging tool used to aggregate, optimize, and package a series of modules into a custom image. This refers to a JRE image, not a jar.
If we only reference the java.base module, we can selectively package it during the packaging process:
The output JRE is a fully usable JRE, and its size differs significantly from the native JDK:
Thus, we can also package our own modules into it.
Note that the value of module-path uses the same separator as the classpath, such as a semicolon in Windows and a colon in Linux; while the value of the add-modules switch is separated by commas.
In this way, we packaged a JRE of only 30MB, and we also included our own module. So what next? Let’s execute the module:
jlink also provides a launcher switch that can compile our module into an executable file similar to the java command, placed in jre/bin.
Please note the format of the launcher – “[command]=[module]”, to distinguish, the command uses an uppercase first letter.
jlink has many switches, and its functionality is not limited to this; for example, it can further compress an already small JRE:
jdeps
This is a dependency analyzer for Java class files.
jmod
Used to create jmod files and view existing jmod files.
Create jmod files:
jdeprscan
This is a static analysis tool for jars, searching for their dependent APIs.
Module Summary
Keywords
Difference Between Module and Jar
Issues to Note with Modules
Module dependencies also have circular dependency issues that need to be noted. For example: Module A requires B; Module B requires A.
Does the IDE support it? Traditional IDEs are based on classpath management for projects, but now they need to support module-path.
Modules packaged as jars can still be used as ordinary jars; no one stops you, at least for now. However, this does not mean that modules are completely meaningless, just like members set to private in class files cannot be accessed externally, you can still access them through reflection, which is the same principle.
Application Scenarios for Modules
First, the most prominent use is to use jlink to package custom images for distribution to small computing units, such as Docker and embedded devices.
Secondly, there will definitely be more and more containers in the future to support direct module execution.
Then, it will have a place in the hot-plugging plugin scenarios for applications.
Finally, it will replace the jar-based execution method.
Let’s wait and see.
Recommended Reading
Possibly the most popular open-source project in China – C/C++ Edition
From UNIX to GitHub: Ten Important Events in the History of Free and Open Source Software
Finally, the long-awaited Java 9 has officially been released!
How many of these excellent mainstream code editors have you used?
Click “Read the Original” for more exciting content