Platform & Advanced APIs
Modules (JPMS)
module-info.java: explicit dependencies (requires) and explicit API surface (exports). The JDK itself is modular; application adoption is optional and, outside libraries, modest.requiresdeclares dependencies;exportsopens packages to compilers and callersopenspermits deep reflection (frameworks!) without exporting the API- Strong encapsulation: non-exported packages are inaccessible — even reflectively
- Unnamed module (classpath) and automatic modules (jars on module path) ease migration
requires transitivere-exports;provides/useswires ServiceLoaderjlinkassembles a minimal runtime image from just the modules you use
module com.acme.orders {
requires java.sql;
requires transitive com.acme.common; // callers of orders see common too
exports com.acme.orders.api; // public API — the ONLY visible packages
opens com.acme.orders.model // reflection access (e.g. for Jackson)
to com.fasterxml.jackson.databind;
provides com.acme.spi.Exporter
with com.acme.orders.CsvExporter; // ServiceLoader wiring
}What modules fix: classpath hell (missing jars surface at startup with clear errors, not NoClassDefFoundError mid-request), accidental API (internals like sun.misc.Unsafe were used because they were reachable; exports make the contract explicit), and bloat (jlink builds a runtime with only the ~20 modules you use — a 40 MB self-contained image instead of a full JDK, relevant for containers).
Migration reality (Core Java II ch. 12): code on the classpath lives in the unnamed module and can read everything, so pre-9 apps run unchanged. A jar dropped on the module path becomes an automatic module readable by named modules. Most applications stop there; full modularization pays off mainly for libraries and platforms. The strong-encapsulation side effects, though, are universal: --add-opens flags for frameworks doing deep reflection into the JDK (Reflection).