Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java modules: readability, exports and reflection boundaries

Last updated: 29 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A named Java module groups packages under a module descriptor and states which other modules it reads and which packages it exports or opens.

Download Java source kit

Java 11+. This is a complete program using JDK classes.

Express the public boundary

A shipping library can export its public quote package while keeping implementation packages internal. requires declares a module dependency. exports permits ordinary use of the named package; opens permits deep reflection under its specified scope. These are different access decisions.

The inspection program runs on the class path. Its own module is unnamed, while String belongs to the named java.base module. This explains the output without claiming that the program is already a packaged named-module application.

A named-module build needs a module-info.java descriptor and a module path. A complete descriptor for a small quote library might export in.aitrove.quote.api while requiring java.net.http. Keep all packages in named modules named; a default-package class belongs to a different sample structure.

Migrate deliberately

Automatic modules can help a dependency participate before it has a descriptor, but their names and broad exposure still need review. Split packages, missing read edges and reflective access failures can appear after moving dependencies off the class path. Check the packaged build rather than assuming IDE completion proves the runtime module graph.

Working program

Java
public class ModuleBoundaryInspection {
    public static void main(String[] args) {
        Module platform = String.class.getModule();
        Module application = ModuleBoundaryInspection.class.getModule();
        System.out.println(platform.getName());
        System.out.println(application.isNamed());
        System.out.println(platform.isExported("java.lang"));
        System.out.println(application.canRead(platform));
    }
}

Output

Output
java.base
false
true
true

Costs and boundaries

This inspection performs a handful of metadata queries. Module resolution is a startup concern and depends on the module graph; it is not the cost of every business-method call. The example verifies the class-path boundary. A separately packaged modular application needs its own descriptor and launch tests.

Common Mistakes

  • exports is not the same as opens.
  • A class-path sample does not become a named module because it uses Module APIs.
  • A compiler release setting does not automatically choose a module path.

Read next

Package ownership, Member access.

java
java-modules
Storage details