Java Modularity Part 6 – Unnamed Module and Automatic Modules

Java modularity

We’ve been looking at Java modularity for the past few weeks. In this article I discuss the unnamed module and automatic modules.

If you’ve missed out any of the previous posts, here are the links:

Types of Java Modules

There are four types of Java modules:

  • System Modules – These are the modules listed when we run the --list-modules command. They include the Java SE and JDK modules.
  • Application Modules – These are the modules we create when we modularize our code. They are defined in the compiled module descriptor (module-info.class) in the JAR file.
  • Automatic Modules – We can include unofficial modules by adding existing JAR files to the module path. The name of the module is derived from the name of the JAR.
  • Unnamed Module – When a class or JAR is loaded onto the CLASSPATH, but not the module path, it’s automatically added to the unnamed module. This is a catch-all module for backward compatibility with legacy Java code.

The Unnamed Module

From Java 9, all code must be placed in modules. Then how do we use legacy Java libraries? We can still use the -classpath JVM flag. We can include all our legacy Java classes on the CLASSPATH. All classes found on the CLASSPATH become the members of unnamed module.

The unnamed module is similar to the default package in Java 8 and earlier. Remember the default (unnamed) package contains any classes that are not specifically placed in a package.

When we execute code that is not in a module, the code is loaded from the CLASSPATH and placed in the unnamed module. We can run un-modularized code in the modularized JDK, but it does not get many modularization benefits.

The unnamed module is not really a module, but can be seen as the default module. If a package has not been added to a named module, then it will automatically be part of the unnamed module. We do this often when we want to run Java 8 (or earlier) programs with a Java 9 (or later) JVM without modularizing them first.

The unnamed module implicitly exports all the types in the packages found in the JAR file. It also reads all other modules. However, because the module is unnamed, a named module cannot use it in a requires directive. This means that a named module cannot depend on the unnamed module. The classes in the unnamed module are only readable by other classes in the unnamed module, or by automatic modules (more on those soon).

Adding Modules to the Unnamed Module

To add the named modules to the default set of root modules, we use the JVM flag –add-modules (,)* where is a module name.

For example to provide access to all java.net.http modules, we would use the following flag:

--add-modules java.net.http

Automatic Modules

Let’s say we’ve modularized our code, but we use a third party library which isn’t modularized? What do we do? We’ve seen we can put the library on the CLASSPATH. This will make it part of the unnamed module, but our named modules won’t be able to use it, because named modules can’t read classes from the unnamed module.

This is where automatic modules come into play. An automatic module is derived from a JAR file that is not modularized, i.e. it has no module descriptor. This includes all JAR files created with Java 8 and earlier. When we put a non-modular JAR file on the module path (not the CLASSPATH) the JVM converts it to an automatic module at runtime.

Important aspects of automatic modules:

  • An automatic module implicitly exports all its packages, so all named modules on the module path can use the public types in the automatic module’s packages.
  • Named modules still must explicitly require the automatic module.
  • An automatic module implicitly requires all other modules on the module path, including other automatic modules and the unnamed module. In other words, it can read all packages exported by all named modules in the module path.
  • If we have multiple automatic modules, each automatic module can read the classes of all other automatic modules.
  • An automatic module is a named module whose name is derived from the JAR file name. If the JAR file is com-incusdata-module.jar, then the module name will become com.incusdata.module. The .jar suffix is removed. The hyphens (-) will be replaced with dots (.).
  • If the JAR file has a version number, e.g. com-incusdata-module-3.1.4.jar, then the version is also removed before the automatic module name is derived. The resulting automatic module name will still be com.incusdata.module.

What’s Next?

I’ve just scratched the surface of the unnamed module and automatic modules. (For more information, IBM DeveloperWorks has some great articles on modularity. As does Baeldung).

In the next post, we’ll look at compiling the module declaration and packaging it into a module.

Please share your views and comments.

Leave a Comment

Your email address will not be published. Required fields are marked *

Code like a Java Guru!

Thank You

We're Excited!

Thank you for completing the form. We're excited that you have chosen to contact us about training. We will process the information as soon as we can, and we will do our best to contact you within 1 working day. (Please note that our offices are closed over weekends and public holidays.)

Don't Worry

Our privacy policy ensures your data is safe: Incus Data does not sell or otherwise distribute email addresses. We will not divulge your personal information to anyone unless specifically authorised by you.

If you need any further information, please contact us on tel: (27) 12-666-2020 or email info@incusdata.com

How can we help you?

Let us contact you about your training requirements. Just fill in a few details, and we’ll get right back to you.

Your Java tip is on its way!

Check that incusdata.com is an approved sender, so that your Java tips don’t land up in the spam folder.

Our privacy policy means your data is safe. You can unsubscribe from these tips at any time.