Appearance
Lesson 02 · Services & Migration
Objectives
After this lesson you will be able to:
- Use
requires transitiveandopens. - Wire a service with
provides/usesandServiceLoader. - Explain automatic and unnamed modules for migration.
requires transitive and opens
requires transitive X— anyone who requires you also readsX(implied readability). Use it whenX's types appear in your public API.opens P— grants deep reflective access to packagePat runtime (for frameworks like Jackson/Hibernate usingsetAccessible), 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 implementationsMigration: 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
requiresit (it has no name). - Automatic module — a plain JAR placed on the module path. It gets a name (from the
Automatic-Module-Namemanifest 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 Xre-exports readability ofXto your dependents (use whenXis in your public API).exports= public compile+runtime access;opens= runtime deep reflection; independent of each other. Anopen moduleopens all packages.- Services: a consumer
usesa service type, a providerprovides … with …, andServiceLoaderdiscovers 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
What does requires transitive X do?
Difference between exports and opens?
A provider declares an implementation with which directive?
Can a named module require the unnamed module?
A plain JAR placed on the module path becomes...
Next: Module 10 Mini-Exam. Run the matching code in labs/src/main/java/com/jse21/m10_jpms/.