Skip to content

Lesson 02 · Services & Migration

Objectives

After this lesson you will be able to:

  • Use requires transitive and opens.
  • Wire a service with provides/uses and ServiceLoader.
  • Explain automatic and unnamed modules for migration.

requires transitive and opens

  • requires transitive X — anyone who requires you also reads X (implied readability). Use it when X's types appear in your public API.
  • opens P — grants deep reflective access to package P at runtime (for frameworks like Jackson/Hibernate using setAccessible), without exporting it for compile-time use.
java
module com.acme.api {
    requires transitive com.acme.model;   // users of com.acme.api also see com.acme.model
    opens com.acme.api.dto;               // reflection-only access (e.g. JSON binding)
    opens com.acme.api.dto to com.fasterxml.jackson.databind;  // qualified open
}

Exam trap

exports = compile-time + runtime access to public members of a package. opens = runtime deep reflection (including private). They're independent: a package can be opens without being exports, and an open module { } opens every package. requires transitive is the only way to make readability transitive.

Services

JPMS formalizes the service-provider pattern:

java
// In the consumer module:
uses com.acme.spi.Codec;                         // "I look these up via ServiceLoader"

// In a provider module:
provides com.acme.spi.Codec with com.acme.impl.GzipCodec;
java
ServiceLoader<Codec> loader = ServiceLoader.load(Codec.class);
for (Codec c : loader) { ... }                   // discovers all provided implementations

Migration: automatic & unnamed modules

Moving a classpath app to modules is bottom-up, easing the transition:

  • Unnamed module — all classpath code lives here. It reads every module and exports everything, but named modules cannot requires it (it has no name).
  • Automatic module — a plain JAR placed on the module path. It gets a name (from the Automatic-Module-Name manifest header, else derived from the filename), exports all its packages, and reads all other modules — a bridge until the JAR is properly modularized.

Gotcha

A named module cannot read the unnamed module — so a modularized library can't depend on a plain classpath JAR. Promote that JAR to an automatic module (put it on the module path) to give it a name your module can requires.

Beyond the exam

jlink builds a custom runtime image containing only the modules your app needs (smaller, faster start). The 1Z0-830 expects you to know module directives, services, and the automatic/unnamed module distinction more than the packaging tools.

Key Takeaways

  • requires transitive X re-exports readability of X to your dependents (use when X is in your public API).
  • exports = public compile+runtime access; opens = runtime deep reflection; independent of each other. An open module opens all packages.
  • Services: a consumer uses a service type, a provider provides … with …, and ServiceLoader discovers implementations.
  • Migration: classpath code is the unnamed module (no name, unusable by named modules); a JAR on the module path becomes an automatic module with a name.

Lesson Quiz

Lesson Quiz · Services & Migration0 / 5
  1. What does requires transitive X do?

    • AHides X
    • BMakes anyone who requires you also read X
    • COpens X for reflection
    • DProvides X as a service
  2. Difference between exports and opens?

    • AIdentical
    • Bexports = public access (compile+runtime); opens = runtime deep reflection
    • Copens is compile-time only
    • Dexports allows reflection on privates
  3. A provider declares an implementation with which directive?

    • Auses
    • Bprovides ... with ...
    • Cexports
    • Drequires
  4. Can a named module require the unnamed module?

    • AYes
    • BNo — the unnamed module has no name
    • COnly platform modules
    • DOnly with opens
  5. A plain JAR placed on the module path becomes...

    • AAn unnamed module
    • BAn automatic module
    • CAn open module
    • DInvisible

Next: Module 10 Mini-Exam. Run the matching code in labs/src/main/java/com/jse21/m10_jpms/.