Example example_resolved-modules
Part of the full Java 9 Jigsaw modules example suite.
|
Authors
Originally written by Martin Lehmann, Kristine Schaal and RĂ¼diger Grammes (cf. original repository). Migrated for Java Modules support documentation of Apache MavenTM in the course of the Maven Support & Care program by Gerd Aschemann (and other team members) as forked repository. Please add discussions, requirements, bugfixes, etc. to the fork instead of the original. |
What is this example about?
Module Dependency Graph, created with DepVis
Example shows …
Example for * resolvedmods: What is loaded? Modules moda, modb (requires moda), modc The Main method in each module outputs the modules in the boot layer: * moda/pkga.AMain: The boot layer contains java., jdk. and moda * modb/pkgB.BMain: The boot layer contains java., jdk., moda, modb * modc/pkgC.CMain: The boot layer contains java., jdk., modc * modb/pkgb.BMain with --add-modules modc: The boot layer contains java., jdk., moda, modb, modc Although only java.base is required, some java.* modules are loaded (java.rmi, java.scripting, java.logging, ...) An automatic module is only loaded if it is also required. First the configuration is created based on the required relationships, then the read edges for automatic modules are added. See also "State of the Module System": *After* a module graph is resolved, therefore, an automatic module is made to read every other named module, whether automatic or explicit.
Output
This example uses golden master testing to ensure output consistency.
The expected output is compared with actual output using verify.sh.
Expected Output
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, moda]
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, moda, modb]
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, modc]
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, moda, modb, modc]
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, moda, modb]
Now we have these boot layer modules:
[java.base, moda, modb]
Now we have these boot layer modules:
[java.base, java.logging, moda, modb]
java.base file://<JAVA_HOME>/jmods/java.base.jmod
moda file://<PROJECT_ROOT>/mlib/moda.jar
modb file://<PROJECT_ROOT>/mlib/modb.jar
Providers:
java.base provides java.nio.file.spi.FileSystemProvider used by java.base
Now we have these boot layer modules:
[java.base, moda, modb]
Actual Output
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, moda]
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, moda, modb]
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, modc]
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, moda, modb, modc]
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, moda, modb]
Now we have these boot layer modules:
[java.base, moda, modb]
Now we have these boot layer modules:
[java.base, java.logging, moda, modb]
java.base file://<JAVA_HOME>/jmods/java.base.jmod
moda file://<PROJECT_ROOT>/mlib/moda.jar
modb file://<PROJECT_ROOT>/mlib/modb.jar
Providers:
java.base provides java.nio.file.spi.FileSystemProvider used by java.base
Now we have these boot layer modules:
[java.base, moda, modb]
Maven 4 Output
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, moda]
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, moda, modb]
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, modc]
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, moda, modb, modc]
Now we have these boot layer modules:
[java.base, java.compiler, java.datatransfer, java.desktop, java.logging, java.management, java.management.rmi, java.naming, java.prefs, java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, java.xml, java.xml.crypto, jdk.charsets, jdk.compiler, jdk.crypto.cryptoki, jdk.crypto.ec, jdk.internal.opt, jdk.jartool, jdk.javadoc, jdk.jdeps, jdk.jfr, jdk.jlink, jdk.localedata, jdk.management, jdk.management.jfr, jdk.naming.dns, jdk.naming.rmi, jdk.security.auth, jdk.security.jgss, jdk.unsupported.desktop, jdk.zipfs, moda, modb]
Now we have these boot layer modules:
[java.base, moda, modb]
Now we have these boot layer modules:
[java.base, java.logging, moda, modb]
java.base file://<JAVA_HOME>/jmods/java.base.jmod
moda file://<PROJECT_ROOT>/mlib/moda.jar
modb file://<PROJECT_ROOT>/mlib/modb.jar
Providers:
java.base provides java.nio.file.spi.FileSystemProvider used by java.base
Now we have these boot layer modules:
[java.base, moda, modb]
Maven 4 Migration
This example has been migrated to Maven 4 using the standard Module Source Hierarchy approach.
Key Characteristics
- Multiple Modules
-
This example compiles three modules (
moda,modb,modc) demonstrating module resolution, not a singlemodmainmodule.The
pom.xmldefines all three modules in the<sources>section. - Multi-Scenario Testing
-
The
m4/run.shscript executes 8 different module resolution scenarios.-
Running with root module
moda(standalone) -
Running with root module
modb(requiresmoda) -
Running with root module
modc(standalone) -
Running with root module
modbplus--add-modules modc -
Running with root module
modbplus automatic modulejavax.json(from../amlib) -
Running with root module
modbplus--limit-modules -
Running with root module
modbplus--limit-moduleson specific JDK modules -
Using
jlinkto create a custom runtime image withmodb, then running from that image
-
- jlink Integration
-
Scenario 8 demonstrates creating a custom runtime image using
jlink.-
Creates minimal runtime with only required modules
-
Demonstrates
jlink --module-pathwith both application modules and JDK modules -
Runs the application from the linked runtime image
-
- Automatic Module Reference
-
The run script references
../amlibfor thejavax.jsonautomatic module in scenario 5, demonstrating that automatic modules are only loaded when explicitly required or added.
JAR Naming for Module-Path and jlink
Maven (4) uses maven-jar-plugin with classifiers, creating JARs with names like:
target/example_resolved-modules-m4-1.0-SNAPSHOT-moda.jar
target/example_resolved-modules-m4-1.0-SNAPSHOT-modb.jar
target/example_resolved-modules-m4-1.0-SNAPSHOT-modc.jar
However, when using jlink, it outputs the actual JAR filenames in its verbose output. The golden master test expects simple JAR names (e.g., moda.jar) for consistency with the original example.
To solve this, compile.sh copies the JARs to mlib/ with simple names:
# Copy JARs to mlib with simple names for jlink
for mod in moda modb modc; do
cp "target/example_resolved-modules-m4-1.0-SNAPSHOT-${mod}.jar" "mlib/${mod}.jar"
done
The run.sh script then uses --module-path mlib instead of --module-path target, ensuring:
-
Simple JAR names in jlink output (matches golden master expectations)
-
Consistent module-path references throughout all 8 test scenarios
-
Compatibility with both direct Java execution and jlink-created runtime images
|
While |