Java - How to create a JPMS Module


In this tutorial, we are going to learn how to create a Java module by hand.


At the end of this tutorial, you would have learned:

  1. What a file is.
  2. How to compile a module.
  3. Describing a module.
Prerequisite Knowledge
  1. Basic Java.
  2. Basic command-line interface.
Tools Required
  1. A CLI shell, such as Command Prompt for Windows, Terminal for Mac, or Bash for Linux.
  2. JDK 9+ path/environment variables already setup.
Concept Overview

Java Module is an abstraction on top of packages that allows for more fine-grained encapsulation.

In the file that defines every module, we can restrict the module’s dependencies, the packages that it exports, services that it consumes or offers, and whether it allows reflection.

The Bank Example

In order to see the concept of modules in action, we will create an example module. For learning purposes, we will not be using an IDE at all in this tutorial.

Let us assume that we are writing software for a bank. This bank has a software engineering team responsible for security.

The module that the security team creates is responsible for:

  1. Biometrics(information).
  2. Vault(security).

To give you a rough idea, later on, we are going to create the following modules and packages:

The Security Module

First we will start with creating the security module.

  1. Create a folder called example. This is where all of our modules live.

  2. Under example, create the following directories(recursively):
    a. com/bank/security/biometrics
    b. com/bank/security/vault

  3. Under com/bank/security, create a file. This file contains the definitions for your module. You do not have to understand this file for now. I will explain it in the next section.

     module {
  4. Under biometrics, create a file. The file only needs two lines, a package declaration and an empty class.

     public class Fingerprint {}
  5. Under vault, create a file. This file also does not contain anything significant.

     public class Guard {}

Your directory tree should now look like this

└── example
    └── com
        └── bank
            ├── security
            │   ├── biometrics
            │   │   └──
            │   ├──
            │   └── vault
            │       └──
The File

At the minimum, a file must include the module name. The module name is declared right after the module keyword.


There are four types of modules.

  1. System modules: modules that came with the JDK.
  2. Automatic modules: regular jar files that are added to the module path(not the same as class path)
  3. Unnamed modules: a catch-all module that includes every jar file on the class path.
  4. Application modules: modules with the file that application developers can create.

The module that we just created is an example of an application module.

Compiling the Security module

To compile the security module, we would navigate back to the directory before the example directory, and use the below javac command:

    javac -d compiled example/com/bank/security/biometrics/ example/com/bank/security/vault/ example/com/bank/security/

You should now see a directory named compiled that contains compiled class files, including the module-info.class.

The compiled directory should look like the tree below.

├── compiled
│   ├── com
│   │   └── bank
│   │       └── security
│   │           ├── biometrics
│   │           │   └── Fingerprint.class
│   │           └── vault
│   │               └── Guard.class
│   └── module-info.class
The exports Directive

Let us try to apply a common module directive: exports. Modify the file and add the exports directive.

    module {

This exports directive allows any other module to read the biometrics package. Without it, other modules would not be able to use the biometrics package normally.

Packaging a module

Next we will package our compiled module into a jar file.

  1. Make a directory called modules. This is where we will place the packaged jar.

  2. Run the command below to package everything under the compiled directory into a jar.

     jar -cvf modules/ -C compiled/ .

If you navigate to the modules directory, you will see the file.

Describing a module

Lastly, we will use a java command to describe our module definitions.

    java -p modules --describe-module

After running the above command, you will see the information below.

    requires java.base mandated

The exports line indicates the package biometrics that we have exported earlier.
The requires line indicates that our module depends on the java.base module. All Java modules implicitly require java.base.
The contains line lists a package that is not exported at all, so this package is only usable to code inside the same module, under normal circumstances.

Solution Code

The whole project zip file can be downloaded here


We have learned how to create our own custom Java module in this tutorial. I skipped the IDE because I believe that compiling by hand is the best way to learn modules.

About the Author

My name is Dimitri Nguyen. I am a Java Developer specializing in backend development on the Java/Spring/MySQL stack.

I can also work on the frontend using Angular/Typescript/JS/HTML/CSS and native Android with Kotlin.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.