December 1, 2017

In our Java 9 Modules Cheat Sheet, we go over the most useful declarations, mechanisms, attributes, and flags for the Java Platform Module System introduced in Java 9.

If you see yourself using Java 9 now or in the future, this 1-page reference for the most important Java 9 modules concepts, keywords, and command line options could be really handy. You can download the Java 9 Modules Cheat Sheet PDF by clicking the image at the bottom of the page.

Java Platform Module System

A long, long time ago in a galaxy right where you and I reside right now, a very smart and ambitious team decided to tackle the issue of modularizing Java. And they succeeded. Naturally, there's a JSR that describes the Java Platform Module System, and a number of JEPs that implement the individual changes in this epic work, including: Encapsulate Most Internal APIs, Modular Run-Time Images, Module System, Modular JDK, among others. This shows the amount of work that went into this change. In this post we'll give a short and mostly incomplete description of the things you need to know to start working with Java 9 modules.

What Is a Java Module?

A Java module is either a JAR file containing a module descriptor, or an exploded version of the module descriptor

A module descriptor is a file that its access rules as it’s dependencies. There are many more details as well, but all you need to do is take a jar file, put in a module-info.class file (compiled from a module-info.java file), and it becomes a named module. A module establishes limits to what the components of a Java program can access within it, think of it as a special mechanism to enhance the visibility rules of the Java language, and strengthen the integrity of the platform.

Module types

Before we talk about how to manipulate and connect the modules, let's see what kind of module types exist, and which of them are preconfigured.

Java SE and JDK modules are the modules provided by the JDK: java.base, java.xml, etc. They export all the packages you could access previously, like java.util. Named application modules are your application modules that contain the module-info.class file; they have to explicitly state which modules they depend on, including what packages and services they need. They cannot read the unnamed module. (see below) Automatic modules are jar files on the module-path without the module-info.class file. The module name is derived from the Automatic-Module-Name MANIFEST.MF entry or the filename of the jar; they can read all modules, including the unnamed module, and are a good way to start the migration to modularity. Unnamed module contains all the jars and classes on the classpath; can read all modules.



module-info.java Contents

To declare a jar file as a named Java module, one needs to provide a module-info.class file, which is, naturally, compiled from a module-info.java file. It declares the dependencies within the module system and allows the compiler and the runtime to police the boundaries/access violations between the modules in your application. Let's look at the file syntax and the keywords you can use.

Declaration Action module module.name Declares a module called "module.name". requires module.name Specifies module dependency, allows module to access public types exported in target module. requires transitive module.name Any modules that depend on this module automatically depend on "module.name" exports pkg.name Says that our module exports public members in package "pkg.name" for every module requiring this one. exports pkg.name to module.name The same as above, but limits which modules can use the public members from the package pkg.name. uses class.name Makes the current module a consumer for service "class.name". provides class.name with class.name.impl Registers "class.name.impl" class a service that provides an implementation of the "class.name" service. opens pkg.name allows other modules to use reflection to access the private members of package "pkg.name". opens pkg.name to module.name Same as above, but limits which modules can have reflection access to the private members in the "pkg.name".

One great thing about the module-info.java syntax is that the modern IDEs would fully support your efforts of writing them. Perhaps all of them would work beautifully, I know that IntelliJ IDEA does content assist, quick fixes of the module files when you import classes from the module you haven't required yet, and so on. I don't doubt Eclipse IDE and NetBeans IDE offer the same.

Java 9 Module Visibility Rules

The Java Platform Module System is heavily about the boundaries and enforcing the visibility rules between the packages and the modules. It can be hard to grasp which Java modules see what, especially if you don't have much experience with the module-info.java files.

In the cheat sheet we have a table of the visibility rules, which was heavily inspired by the awesome blog posts about the Java 9 modules by Nicolai Parlog. Here's what he writes about the visibility, check out the summary section of this blog post. Here's the table of the visibility rules in the cheat sheet

In this table we are able to distinguish between the compile time access and the runtime access, because you can relax what modules are allowed to see providing options on the command line when you start your java process. Read it like this, when you use a certain mechanism, the code on the left in the column like Compile time access, has the access to the members of the code in the module either public, or private through the reflection if it is specified in the table. If a module has reflective access to the private types, it has normal access to the public types too.

Important MANIFEST.MF Attributes

If you're ready to modularize your code, but are worried about the dependencies, and whether they'll modularize their code in time, worry a bit less. Of course a modular jar won't see the classes on the classpath and in the non-modular jars by default. So one needs a minimally intrusive way to make a jar pretend it’s modular, without complex code changes that'll break everything. Such a way, luckily, exists.

You can specify some attributes in the MANIFEST.MF file of the jar.

Attribute Action Automatic-Module-Name: module.name Declares stable module name for non-modularized jar. Add-Exports: module/package Exports the package to all unnamed modules. Add-Opens: module/package Opens the package to all unnamed modules.

With these options you can control what a normal, non-modular jar file looks like in the module system, which provides you with an easier path for migrating an existing non-modular application.

Command Line Options for Java 9 Modules

In addition to all the options and the keywords in the module-info.java file, you need to know a number of command line options for the java command, which support the module system at runtime. Here are the most essential flags:

Flag Action --module-path or (-p) Specifies the module path; provide one or more directories that will contain your modules. --add-reads src.module=target.module A command-line equivalent of the requires clause in a module declaration. --add-exports src.module/pkg.name=target.module A command line equivalent of the exports clause. --add-opens src.module/pkg.name=target.module A command line equivalent of the open clause in a module description. --add-modules Displays the names and version strings of the observable modules. --list-modules Displays the names and version strings of the observable modules. --patch-module Adds or overrides classes in a module. Replaces -Xbootclasspath/p. --illegal-access=permit|warn|deny Relaxes strong encapsulation of the module system to show one global warning, show all warnings, or fail with errors respectively; The Java 9 default is permit.

Naturally, this isn’t a full or rigorous description of the Java Platform Module System, and I encourage you to learn more about it. There's a number of resources that you can try for that: Nicolai's blog, Jigsaw quickstart, State of the module system, the Module System JEP itself, and I'm sure countless blog posts all over the internet. But as a starting point, and as a quick reference, this blog post can be a valuable resource.

Final Thoughts

In this post we looked at some of the Java Platform Modules System, or for short the Java 9 modules. We briefly covered the overall concepts, module files, keywords, how providers and services work and some command line options. These are probably the most frequently used parts of the Java 9 module system a developer will need to know about, whether developing with or migrating to Java 9 modules.

Download the Java Platform Module Cheat Sheet PDF

Ready to download a PDF copy of our Java module cheat sheet? Click the image below!

Additional Resources

This post continues the cheat sheet series aiming to provide you with concise details about various technical topics. A blog post always comes with a cheat sheet that goes into more details about each topic. If you haven't seen any of our cheat sheets, check out a few in the list below:

And many more. You can see all of them in our Java cheat sheet collection.

See Cheat Sheets