Skip to content

Lesson 01 · Modules Basics

Objectives

After this lesson you will be able to:

  • Declare a module with module-info.java (requires, exports).
  • Explain strong encapsulation and readability.
  • Tell the module path from the classpath.

module-info.java

A module is a named, self-describing set of packages. Its declaration lives in module-info.java at the module's source root:

java
module com.acme.app {
    requires com.acme.util;        // I depend on (read) this module
    requires java.sql;             // platform modules too
    exports com.acme.app.api;      // expose THIS package to others
}
  • requires X — this module reads X; you can use X's exported types.
  • exports P — package P is accessible to other modules; packages not exported are strongly encapsulated (invisible even via reflection by default).
java
exports com.acme.app.internal to com.acme.tests;   // qualified: only to named modules

Exam trap

A module reads only what it requires — there is no transitive readability unless the dependency uses requires transitive (next lesson). A package is hidden unless **exports**ed, even if its types are public. java.base is implicitly required by every module — you never write requires java.base.

Strong encapsulation

Before modules, public meant "visible everywhere on the classpath." With modules, a public type in a non-exported package is invisible to other modules — encapsulation the compiler and runtime enforce. This is the headline benefit of JPMS.

Module path vs classpath

ClasspathModule path
UnitJARs/dirs of classesmodules (with module-info)
Encapsulationnone (public is global)enforced by exports
Flag-cp / -classpath--module-path / -p, run with -m
bash
javac -d out --module-source-path src $(find src -name "*.java")
java --module-path out -m com.acme.app/com.acme.app.Main

SDET note

Modules make "what's public API vs internal" explicit and enforced — useful when testing a library, since tests must requires the module and can only touch exported packages (or use a qualified exports … to / opens for white-box tests).

Key Takeaways

  • A module is declared in module-info.java with requires (what it reads) and exports (what it exposes). java.base is implicit.
  • A non-exported package is strongly encapsulated even if its types are public.
  • Readability is not transitive by default; exports … to does a qualified export to named modules only.
  • The module path (--module-path/-p, run -m) enforces encapsulation; the classpath does not.

Lesson Quiz

Lesson Quiz · Modules Basics0 / 4
  1. Which directive exposes a package to other modules?

    • Arequires
    • Bexports
    • Cuses
    • Dopens
  2. Do you need requires java.base; ?

    • AYes, always
    • BNo — it's implicit for every module
    • COnly for I/O
    • DOnly on the module path
  3. A public class is in a package that is NOT exported. Can another module use it?

    • AYes — public is global
    • BNo — non-exported packages are encapsulated
    • COnly via reflection
    • DOnly on the classpath
  4. Module A requires B, and B requires C. Can A read C's exported types?

    • AYes — readability is transitive
    • BNo — unless B uses requires transitive C
    • COnly platform modules
    • DOnly if C exports to A

Next: Services & Migration. Run the matching code in labs/src/main/java/com/jse21/m10_jpms/.