All topics
library
advanced

Java Platform Module System (JPMS)

Understand Java modules: module-info.java, exports, requires, and strong encapsulation.

A module is a named group of packages that declares what it needs and what it shares.

Modules = apartments in a building. Each apartment (module) has a front door (exports) and private rooms (internal packages). The building directory (module-info) says who can visit whom.

Key Concepts

1
    module com.shop.orders {
      requires com.shop.model;        // what I depend on
      requires java.sql;
2
      exports com.shop.orders.api;    // what others may use
      opens   com.shop.orders.dto;    // what reflection may reach
3
      provides PaymentProvider with StripeProvider;    // an SPI
    }
4
Before modules, public meant public to everyone. A class you intended as internal was reachable from any code on the classpath, so "internal" was a naming convention and nothing more.
public
5
With modules, a public class in a non-exported package is unreachable. That is strong encapsulation, and it is the point.
6
The three guarantees.
    strong encapsulation    non-exported packages are invisible
    reliable configuration  a missing module fails at startup, not on
                            first use halfway through a request
    no split packages       two modules cannot share a package name
7
exports and opens differ in a way that matters for frameworks:
exportsopens
8
    exports   compile-time and runtime access to the public API
    opens     reflective access to everything, including private
9
Hibernate and Jackson need to reach private fields, so a DTO package gets opens, not exports. Without it you get InaccessibleObjectException at runtime, and setAccessible(true) does not help — the module system outranks it.
opensexportsInaccessibleObjectExceptionsetAccessible(true)
10
The JDK itself is modular. java.base is always there; java.sql, java.net.http and the rest are separate. That is what lets jlink build a runtime image containing only what you use, which matters for container size.
java.basejava.sqljava.net.httpjlink
11
Classpath code still works. It lands in the unnamed module, which can read every exported package. So an application can stay on the classpath indefinitely, and most still do.
12
Be honest about adoption. Library authors ship module-info so modular consumers work; most applications never write one. Knowing opens versus exports, and why a missing opens breaks reflection, is the part that comes up.
module-infoopensexports
13
What the interviewer is probing.1. "What is the difference between exports and opens?" Probing: the distinction frameworks depend on. Stalls: "They are the same." Moves up: exports gives compile and runtime access to public API; opens permits deep reflection including private members, which Hibernate and Jackson need.
14
2. "Your framework throws InaccessibleObjectException. Why?" Probing: module enforcement beating setAccessible. Stalls: "Add setAccessible(true)." Moves up: the package is not opened, and the module system outranks setAccessible — the fix is opens, or --add-opens at launch.
15
3. "What does 'strong encapsulation' mean here?" Probing: what modules changed. Stalls: "Classes are private." Moves up: a public class in a non-exported package is unreachable from other modules, which package-level visibility never achieved.
16
4. "Why has application adoption been slow?" Probing: whether you can be honest about it. Stalls: "Everyone uses it." Moves up: the classpath still works via the unnamed module, so the benefit rarely justifies the migration; library authors ship module-info, most applications do not.