Java Module System (JPMS)
AdvancedThe Java Platform Module System (JPMS) introduces strong encapsulation and explicit dependency declarations at the module level.
Overview
The Java Platform Module System, introduced in Java 9, divides the JDK and applications into named modules. Each module declares its dependencies (requires) and what it exposes (exports). This enables strong encapsulation — internal packages are hidden by default — and reliable configuration at compile time and startup. JPMS is foundational to the JDK itself and increasingly adopted in large Java applications.
module-info.java
A module is defined by a module-info.java file at the source root. It declares the module name, its dependencies, and its public API.
requires: declares a dependency on another module. exports: makes a package accessible to other modules. opens: allows reflective access (needed by frameworks like Spring). uses/provides: service loader declarations.
// src/module-info.java
module com.example.myapp {
// Dependencies
requires java.base; // implicit — always required
requires java.sql;
requires com.fasterxml.jackson.databind;
// What we expose
exports com.example.myapp.api;
exports com.example.myapp.model;
// Reflective access for frameworks (Spring, Hibernate, etc.)
opens com.example.myapp.config to spring.core;
opens com.example.myapp.model to com.fasterxml.jackson.databind;
// Service declarations
uses com.example.myapp.spi.PaymentProvider;
provides com.example.myapp.spi.PaymentProvider
with com.example.myapp.impl.StripePaymentProvider;
}Module Types
Named modules: have module-info.java, strong encapsulation enforced. Unnamed module: the classpath — all classes, no encapsulation, exists for backward compatibility. Automatic modules: JARs on the module path without module-info — module name derived from JAR filename, exports everything.
Migrating to modules is incremental: you can mix named and unnamed modules.
// Compile a module
javac -d out --module-source-path src \
$(find src -name "*.java")
// Run a module
java --module-path out \
--module com.example.myapp/com.example.myapp.Main
// List modules in the JDK
java --list-modules
// Show module info
java --describe-module java.sql
// Check dependencies
jdeps --module-path lib --module com.example.myappStrong Encapsulation and Migration
Without a module-info.java, code runs in the unnamed module with access to the full classpath. When you add module-info.java, packages not listed in exports become inaccessible.
Common migration steps: add module-info.java, fix missing requires, add opens for reflection-heavy frameworks, use --add-opens as a temporary escape hatch during migration.
// Temporary escape hatch during migration (JVM arg)
// --add-opens java.base/java.lang=ALL-UNNAMED
// --add-exports java.base/sun.nio.ch=ALL-UNNAMED
// Checking encapsulation violations before full migration
jdeps --jdk-internals myapp.jar
// Multi-release JAR with module-info in Java 9+
jar --create --file mylib.jar \
--main-class com.example.Main \
-C out/classes . \
--release 9 -C out/module-info .Key Points to Remember
- module-info.java declares requires (dependencies) and exports (public API).
- Packages not exported are inaccessible to other modules — strong encapsulation.
- opens grants reflective access; needed by Spring, Hibernate, Jackson.
- Unnamed module = classpath; automatic module = JAR on module path without module-info.
- Use --add-opens and --add-exports as temporary migration helpers, not permanent solutions.
Practice Java Module System (JPMS) in the Playground
Run and modify code directly in your browser - no setup needed.
Interview Questions
Sign in to ask AriaWhat problem does JPMS solve that packages and JARs did not?
What is the difference between exports and opens in module-info.java?
What is an automatic module and when is it created?
Why might a Spring Boot application need --add-opens when run with modules?
How do you migrate a large classpath-based application to JPMS incrementally?
Ask Aria about Java Module System (JPMS)
Your personal AI tutor — ask anything about this concept