Java Modules

Introduction

Java modules were introduced in Java 9 as part of the Project Jigsaw. The module system, also known as the Java Platform Module System (JPMS), aims to provide a more scalable and flexible way to handle large applications and libraries. Modules help improve the structure, security, and maintainability of Java applications by enabling strong encapsulation and clear dependencies between different parts of the application.

Key Points:

  • Encapsulation: Modules allow you to explicitly specify which parts of your code are accessible to other modules.
  • Dependency Management: Modules provide a way to declare dependencies between different parts of your application, making it easier to manage and understand.
  • Improved Security: By restricting access to internal APIs and only exposing necessary parts of your code, modules enhance the security of your application.

Table of Contents

  1. Creating a Module
  2. The module-info.java File
  3. Defining Module Dependencies
  4. Exporting Packages
  5. Requiring Modules
  6. Using Services
  7. Real-World Example
  8. Conclusion

1. Creating a Module

To create a module, you need to structure your project with a module-info.java file at the root of your module’s directory. This file contains the module declaration and specifies the module’s dependencies and exported packages.

Example:

my-module/
    ├── src/
    │   ├── main/
    │   │   ├── java/
    │   │   │   ├── com/
    │   │   │   │   ├── example/
    │   │   │   │   │   ├── MyModule.java
    │   │   │   ├── module-info.java
    ├── build/

2. The module-info.java File

The module-info.java file is where you define your module’s name, its dependencies, and the packages it exports.

Example:

module com.example.mymodule {
    // Exporting a package
    exports com.example;

    // Requiring another module
    requires java.logging;
}

Explanation:

  • module com.example.mymodule: Declares a module named com.example.mymodule.
  • exports com.example: Specifies that the com.example package is accessible to other modules.
  • requires java.logging: Declares a dependency on the java.logging module.

3. Defining Module Dependencies

Modules can depend on other modules. You define these dependencies using the requires keyword in the module-info.java file.

Example:

module com.example.mymodule {
    requires java.sql;
    requires java.xml;
}

Explanation:

  • requires java.sql: Indicates that this module depends on the java.sql module.
  • requires java.xml: Indicates that this module depends on the java.xml module.

4. Exporting Packages

To make a package accessible to other modules, you use the exports keyword in the module-info.java file.

Example:

module com.example.mymodule {
    exports com.example.api;
}

Explanation:

  • exports com.example.api: Makes the com.example.api package accessible to other modules.

5. Requiring Modules

Modules can specify dependencies on other modules using the requires keyword. This helps to manage dependencies and ensures that all required modules are available at compile time and runtime.

Example:

module com.example.mymodule {
    requires java.base;
    requires com.external.library;
}

Explanation:

  • requires java.base: All modules implicitly require the java.base module, but you can explicitly declare it if needed.
  • requires com.external.library: Declares a dependency on an external module named com.external.library.

6. Using Services

Modules can provide and consume services. This is useful for implementing the Service Provider Interface (SPI) pattern. You use the provides and uses keywords in the module-info.java file.

Example:

module com.example.mymodule {
    requires java.logging;
    exports com.example.api;

    // Providing a service
    provides com.example.api.MyService with com.example.impl.MyServiceImpl;

    // Consuming a service
    uses com.example.api.MyService;
}

Explanation:

  • provides com.example.api.MyService with com.example.impl.MyServiceImpl: Specifies that com.example.impl.MyServiceImpl is an implementation of the com.example.api.MyService service.
  • uses com.example.api.MyService: Indicates that this module uses the com.example.api.MyService service.

7. Real-World Example

Let’s create a simple example with two modules: com.example.mymodule and com.example.util.

com.example.util Module

Directory Structure:

com.example.util/
    ├── src/
    │   ├── main/
    │   │   ├── java/
    │   │   │   ├── com/
    │   │   │   │   ├── example/
    │   │   │   │   │   ├── util/
    │   │   │   │   │   │   ├── StringUtils.java
    │   │   │   ├── module-info.java
    ├── build/

module-info.java:

module com.example.util {
    exports com.example.util;
}

StringUtils.java:

package com.example.util;

public class StringUtils {
    public static String reverse(String input) {
        return new StringBuilder(input).reverse().toString();
    }
}

com.example.mymodule Module

Directory Structure:

com.example.mymodule/
    ├── src/
    │   ├── main/
    │   │   ├── java/
    │   │   │   ├── com/
    │   │   │   │   ├── example/
    │   │   │   │   │   ├── MyModule.java
    │   │   │   ├── module-info.java
    ├── build/

module-info.java:

module com.example.mymodule {
    requires com.example.util;
}

MyModule.java:

package com.example;

import com.example.util.StringUtils;

public class MyModule {
    public static void main(String[] args) {
        String original = "Hello, World!";
        String reversed = StringUtils.reverse(original);
        System.out.println("Original: " + original);
        System.out.println("Reversed: " + reversed);
    }
}

Explanation:

  • com.example.util: This module exports the com.example.util package containing the StringUtils class.
  • com.example.mymodule: This module requires the com.example.util module and uses the StringUtils class to reverse a string.

8. Conclusion

Java modules provide a powerful way to encapsulate and manage dependencies in your Java applications. By defining module dependencies and exporting only the necessary packages, you can create more maintainable and secure applications. Understanding and utilizing the module system can significantly improve the organization and scalability of your projects.

Leave a Comment

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

Scroll to Top