Modules in Java

Modules in Java were introduced in Java 9 version. There were many other features that were added in Java 9, in addition to Modularity. But, this was an important decision made to modularize entire Java.

The entire JDK and the rt.jar file were broken down into different modules containing packages. Even the coders can develop their own code using modules to make the code more effective, maintainable and sustainable.

Why Modules?

Java keeps coming up with new features with every new release of its JDK. Java is known to be backward compatible. That is, the new features will not replace old ones; but, will be added to them. Therefore, the size of the rt.jar (runtime) file keeps increasing with every update. The JDK 8 is known to have the rt.jar file of size around 64MB, which is huge in size.

This jar file is present in every project, that we create. Having such a heavy jar file in every project is not optimal.

Keeping this in mind, Java has broken down the entire rt.jar file into small modules. Therefore, now we can import only those modules from the rt.jar file that we want to work with.

Therefore, a Module can be defined as a collection of related packages that are grouped together under a single module. For example, if we want to work with XML, then we have a module called java.xml. It contains all the packages related to XML operations. The java.base is another module which has all the packages providing the basic features.

Packages are available for usage by every class that imports them. Whereas, modules can be made available only to certain other modules. Therefore, enabling control over their visibility.

How to define Modules in Java?

Whenever we are working with modules, we need to specify two things:

  1. Module Name – Every module needs to have a name to it.
  2. Module Configuration – Module configurations are done inside the module-info.java file. This file has to be created internally in every module to specify the module’s configurations. These configurations can be done with the help of two important keywords:
    • requires keyword : This helps in specifying all the modules that the current module requires and is dependent on.
    • exports keyword : This helps in declaring the packages present within a module as public. That is, they are made visible and available to use by other modules.

Every module needs to have only one module-info.java file created. It specifies the modules that it requires and the packages that it exports.

Therefore, we cannot import packages from other modules unless they are exported by that module. Neither can we import a package if we do not mention the module the package is present in, as requires. This way, we can have the control over the usage and visibility of the packages.

Advantages of using Modules

The main advantages of using Modules are:

  • We can impose constraints over the visibility of the code. This hugely improves the standards of coding.
  • If we miss to include any modules that we require, it throws an error at the compile time. And not at the run time. This can save a lot of coding efforts while working on huge projects. Because runtime errors can be terrible to resolve at times.
  • Also, we do not have to contain the entire rt.jar file in our project. Because now we can only import modules that we want to work with.

Therefore, Modules introduced in Java; reduces the space and programming efforts; and hence providing an optimal way of programming.

Now let’s see how we put everything what we discussed so far, to create the simple Calculator using Modules.

Creating the simple Calculator using Modules

Step 1. Use an IDE (example; Eclipse IDE) to work with modules.

Step 2. If you are using Eclipse IDE, follow the below steps to create a module;

  • Right-click on the Project Name -> New -> Module -> Module Name. A new module gets created with the given name.
  • Under the created module there will be a src folder. Right-click on src -> New -> New class. A new class gets created.
  • Right click on src -> New -> module-info.java. The configuration file gets created.

Step 3. We will create two modules, one containing the com.codesteps package with the main class in it. The other containing the packages com.codesteps.util and com.codesteps.internal having the Calculator and the AddHelper classes respectively.

Here is the code;

Module 1 – codesteps.util

We will add two packages into it; com.codesteps.util & com.codesteps.internal. com.codesteps.internal, we will use it, only in this module. So, outside modules can not have the visibility of this package.

Package 1 : com.codesteps.util

  package com.codesteps.util;
  import com.codesteps.internal.AddHelper;

  public class Calculator {
                  AddHelper help = new AddHelper();
                  // adding integers
                  public int add(int i, int j) {
                                  return help.add( i,  j);
                  }
  }

Package 2 : com.codesteps.internal (as mentioned before, this is internal to this module)

  package com.codesteps.internal;

  public class AddHelper {
                 public int add (int i, int j) {
                                 return i+j;
                }
  }

The configuration file, module-info.java– This is the place where we add the configuration to export the packages to outside of the module; so, other modules can access these packages. In every module, all the packages defined in it are by default private. And hence, can be used within the module itself. In order to make them public, we need to define them in this configuration file, using the exports keyword as shown in the below code;

Only the packages that are exported are visible and can be used by other modules. The rest of the packages remain internal to the module. Observe that, com.codesteps.internal package is not exported;

module codesteps.util {
                exports com.codesteps.util; // exporting this package
}

Now, we will add another module, the main module; from where we access the classes defined in codesteps.util module. I hope you are following; if not, please read this from the beginning;

Module 2 – codesteps.main

We will add only one package in this module; with the main class MyClass, where main method is defined. So, this is the star point of our program.

Package 1: com.codesteps

  package com.codesteps;
  import com.codesteps.util.Calculator;

  public class MyClass {
                public static void main(String args[]) {
                                Calculator c = new Calculator();
                                int result = c.add(4,5);
                                System.out.println(result);
                }
  }

The Configuration file, module-info.java– This is the place where we import other modules, to use within this module. When you want the module to import a package from another module, it has to define the required module inside this configuration file using the requires keyword as shown in the code below;

module codesteps.main {
                requires codesteps.util;  // importing this module
}

Now, we are done with our code. Let’s Run it and observe the results.

Please add your feedback in below comments section. We will discuss more topics in upcoming Articles.

Add a Comment

Your email address will not be published.