Skip to main content

Java Platform Module System (JPMS) plays a crucial role in organizing and managing code dependencies. While some might argue that JPMS modules are simply artifacts, in reality, they are much more than that.

Understanding JPMS

Before delving into the reasons why JPMS modules are not artifacts, let's first understand what they entail. JPMS is a module system introduced in Java 9, allowing developers to create modular applications. It breaks down monolithic codebases into smaller, manageable pieces called modules, each with its own defined boundaries and dependencies.

Modules as Building Blocks

One of the primary reasons why JPMS modules should not be considered as artifacts is their role as fundamental building blocks of a Java application. Artifacts typically refer to compiled code or binary outputs, while JPMS modules encapsulate not only the code but also its dependencies, resources, and configuration details.
For example, consider a banking application composed of several modules, such as core, usermanagement, transaction, and reporting. Each module defines its own set of classes, interfaces, and resources, along with explicit dependencies on other modules. These boundaries and dependencies are crucial for maintainability, scalability, and modularization of the application.

Explicit Dependencies and Encapsulation

Unlike traditional artifacts that can be thrown together ad hoc, JPMS modules require explicit dependencies and encapsulation. The module-info.java file, found in each module, explicitly specifies the module's dependencies using the requires keyword. This allows for fine-grained control over which classes and resources are accessible to other modules.

By enforcing these dependencies, JPMS modules promote a cleaner and more modular architecture. For example, if the usermanagement module depends on the core module, it will only have access to the classes and resources explicitly exposed by the core module. This enhances encapsulation, preventing unwanted direct dependencies and improving the overall maintainability of the codebase.

Strong Modular Boundaries

Another compelling reason why JPMS modules are not artifacts lies in their ability to establish strong boundaries between different parts of an application. Each module acts as an isolated unit, shielding its implementations and internals from the outside world.
Consider a scenario where there is a flaw in the implementation of the usermanagement module. Due to the strong modular boundaries, this flaw will not directly impact other modules, thereby containing the potential damage. In the absence of JPMS modules, such issues can easily ripple through the codebase, making debugging and maintenance a nightmare.

Versioning and Dependency Management

Artifacts typically come with versioning and dependency management tools, such as Maven or Gradle, but JPMS modules take it a step further. JPMS modules not only provide versioning capabilities but also enforce them explicitly within the module declarations.

The module-info.java file allows developers to specify the module's version range using the requires keyword. This ensures that the correct version of a module is used at compile-time and runtime, preventing version conflicts that often plague large-scale projects. By integrating versioning and dependency management at the module-level, JPMS modules enhance the overall reliability and robustness of an application.

JPMS modules are much more than mere artifacts in the Java ecosystem. They serve as essential building blocks, ensuring explicit dependencies, strong modular boundaries, and versioning capabilities. By embracing the modular nature of JPMS, developers can build more maintainable, scalable, and robust applications. So, it's clear that JPMS modules should not be dismissed as mere artifacts, but rather be acknowledged as powerful assets in modern Java development.

Integrate People, Process and Technology