Modules (JPMS)
The Java Platform Module System (Java 9) groups packages into modules with explicit boundaries. A module-info.java file declares:
requires: modules this one depends on.exports: packages other modules may use. Everything else is hidden, evenpublicclasses.opens: packages open to deep reflection, which frameworks like Hibernate and Jackson need.provides … withanduses: service loading.
The JDK itself is modular (java.base, java.sql, java.net.http…), which lets jlink build a small custom runtime containing only the modules your app needs.
Most Spring Boot applications still run on the classpath without a module-info.java. Modules shine in libraries and in apps that want strong encapsulation or tiny runtimes. Java 25's import module java.base; is a separate, simpler feature that imports every package a module exports.
Example
// src/main/java/module-info.java
module com.javaatlas.billing {
requires java.net.http; // uses the HTTP client
requires transitive java.sql; // our public API exposes java.sql types
exports com.javaatlas.billing.api; // the public API
opens com.javaatlas.billing.model to com.fasterxml.jackson.databind; // reflection for JSON
}# See which modules a JAR needs, then build a runtime with only those
jdeps --print-module-deps target/app.jar
jlink --add-modules java.base,java.net.http,java.sql --output custom-jre --strip-debug --no-header-files
./custom-jre/bin/java -jar target/app.jarCommon mistake
Adding module-info.java to a Spring Boot app without opening packages for reflection. The frameworks then fail with InaccessibleObjectException.
Under the hood
Strong encapsulation of JDK internals (the default since Java 16, with no opt-out since 17) is why old libraries that used sun.misc or private JDK fields broke on upgrade; the fix is a newer library version or, temporarily, --add-opens. Split packages (the same package in two modules) are forbidden and often block migrations. A plain JAR on the module path becomes an automatic module named after the JAR.
Check yourself
Which tool builds a smaller custom Java runtime?
How this connects
Know these first
Where this leads
You've reached the end of this thread. Try a learning path for what's next.
Part of Upgrade from Java 8 to Java 25.
Was this lesson helpful?
Finished reading? Mark it complete to track your progress.