Working with Modules (JPMS) JAVA 9+

1. Understanding Module System

ConceptDetail
ModuleNamed collection of packages + dependencies
Strong encapsulationOnly exported packages accessible
Reliable configDependencies declared at compile/runtime
Module pathReplaces classpath (or coexists)

2. Creating Module Declarations (module-info.java)

Example: module-info

module com.example.app {
    requires java.sql;
    requires transitive com.example.api;
    requires static lombok;
    exports com.example.app.service;
    exports com.example.app.internal to com.example.tests;
    opens com.example.app.model to jackson.databind;
    uses com.example.api.PaymentProvider;
    provides com.example.api.PaymentProvider with com.example.app.StripeProvider;
}
DirectiveUse
requiresDependency
requires transitiveRe-exported to consumers
requires staticCompile-time only
exportsPublic API
opensReflective access
uses / providesServiceLoader

3. Using requires Directive

FormEffect
requires XCompile + runtime dependency
requires transitive XConsumers automatically get X
requires static XCompile only (e.g., annotations)

4. Using exports Directive

FormDetail
exports pkgOpen to all modules
exports pkg to A, BQualified export
Affectspublic types in package only

5. Using opens Directive

FormDetail
opens pkgReflective deep access at runtime
opens pkg to XQualified open
open module M {...}Opens all packages

6. Using provides and uses Directives

DirectiveUse
uses XConsumer of service interface X
provides X with YY implements service X
DiscoveryServiceLoader.load(X.class)

7. Understanding Service Loading

Example: ServiceLoader

ServiceLoader<PaymentProvider> providers = ServiceLoader.load(PaymentProvider.class);
providers.stream()
    .map(ServiceLoader.Provider::get)
    .forEach(p -> p.process(payment));
MethodUse
load(cls)Find providers
iterator() / stream()Iterate
findFirst()First provider

8. Compiling Modular Applications

CommandDetail
javac --module-source-path src -d out --module com.xMulti-module
--module-path modsModule dependencies

9. Running Modular Applications

CommandDetail
java --module-path mods -m com.x/com.x.MainRun module's main class
java -p mods -m com.xShort form

10. Working with Automatic Modules

AspectDetail
SourcePlain JAR on module path
NameFrom manifest Automatic-Module-Name or filename
ExportsAll packages
ReadsAll other modules
Use caseMigration bridge

11. Understanding Unnamed Module

AspectDetail
SourceCode on classpath
ReadsAll modules
Cannot be requiredNamed modules can't depend on it

12. Migrating to Modules

StepDetail
1. Bottom-upStart with leaves of dependency graph
2. Add module-infoDeclare requires/exports
3. Use jdepsAnalyze dependencies (jdeps --generate-module-info)
4. Bridge with automatic modulesUntil all deps modularized
jlink --module-path $JAVA_HOME/jmods:mods \
      --add-modules com.example.app \
      --launcher run=com.example.app/com.example.app.Main \
      --strip-debug --no-header-files --no-man-pages --compress=2 \
      --output runtime
AspectDetail
OutputCustom runtime image with only needed modules
BenefitSmaller distribution, faster startup
RestrictionAll deps must be explicit modules