Other meanings of Java Platform Module System
Java platform
The Java Platform Module System (JPMS), introduced in Java 9, defines modular JAR files and module descriptors. It gives Java programs explicit boundaries for dependencies, exported packages, services, and reflective access, while preserving compatibility with much existing class-path software.
JPMS makes dependencies and package boundaries explicit at compile time and run time. A module is a named unit that contains packages, resources, and a descriptor; its declared requires dependencies form a directed readability graph, while exports controls which packages other modules may access.1 This contrasts with the traditional class path, where classes are broadly visible and missing or conflicting dependencies are often detected only during execution.
The descriptor is normally written as module-info.java and compiled to module-info.class at the root of a modular JAR. The Java compiler and launcher resolve modules from the module-path, which can contain application modules, library modules, and portions of the JDK itself.2 JPMS therefore supplies both a language-level declaration mechanism and a deployment-time configuration model.
A module descriptor states the module's name, dependencies, exported packages, services, and qualified or open access. Common directives include requires, exports, opens, uses, and provides ... with; requires transitive propagates readability to downstream modules, while requires static expresses a compile-time-only dependency.3
Exports govern ordinary compiled access, whereas opens govern deep reflection, such as reflective access to non-public members by a framework. A module can be entirely open with open module, or open selected packages with qualified opens. These distinctions matter to dependency-injection, serialization, persistence, and testing libraries, because a package may be public yet still inaccessible reflectively unless it is opened.
JPMS supports gradual migration through the unnamed module, automatic modules, and command-line options. Code loaded from the class path belongs to the unnamed module and can interact broadly with named modules; a JAR placed on the module path without a descriptor becomes an automatic module whose name is derived from its metadata or filename.4
This compatibility layer is useful but not equivalent to a carefully designed descriptor. Automatic modules implicitly read other modules and export all their packages, so they provide weaker encapsulation. Migration can also expose split packages, concealed internal APIs, illegal reflective access, and assumptions about class-path ordering. Options such as --add-exports, --add-opens, and --add-reads can provide transitional exceptions, but they should not replace stable module declarations.
JPMS also acts as a service-discovery and JDK-composition mechanism. A module can declare that it uses a service interface and another can provides an implementation; ServiceLoader then discovers providers without the consumer naming implementation classes directly.5 This supports replaceable providers while keeping implementation packages unexported.
The JDK itself is modularized into named modules such as java.base, which is implicitly required by every named module, and optional modules for areas such as desktop or management APIs.1 The jlink tool can assemble a smaller custom runtime image from selected modules, an often-overlooked operational benefit. Conversely, module names are distinct from package names, and a module may export no packages at all while still supplying services or resources.
JPMS terminology and behavior described here follow the Java Language Specification and OpenJDK module-system design documentation; command-line workarounds may vary across JDK releases.
Help improve the encyclopedia. Reports go straight to the site manager.