10.3 Modular Compilation, Packaging, and CLI Execution

Key Takeaways

  • Modular compilation with javac relies on --module-path (-p) to locate precompiled module dependencies and --module-source-path to compile multiple module source trees in a single atomic invocation.
  • The java runtime launches modular applications using --module-path (-p) and --module (-m), specified in the standard format <module-name>/<main-class-name> or <module-name> if the main class is embedded in the modular JAR.
  • The separator between module name and main class in CLI invocations is strictly a forward slash (/), regardless of operating system platform.
  • The jar tool packages modular binaries, checks descriptor validity, and embeds execution metadata including the main class (--main-class) and version string (--module-version) directly into module-info.class.
  • The jdeps tool performs static bytecode dependency analysis, detects missing module declarations, and scans for illegal references to deprecated internal JDK APIs with --jdk-internals.
Last updated: September 2026

Modular Compilation, Packaging, and CLI Execution

The Java Platform Module System introduces dedicated command-line options across standard JDK tools including javac (compiler), jar (archiver), java (launcher), and jdeps (dependency analyzer). For the 1Z0-830 exam, mastering exact CLI flag syntax, multi-module source path structures, modular JAR descriptors, runtime execution flags, and static analysis diagnostics is essential.


1. Modular CLI Options Master Matrix

Understanding the standard command-line flags and their short forms across the JDK toolset is heavily tested on the exam.

Option / FlagShort FlagToolDescription
--module-path <path>-pjavac, java, jar, jdepsSpecifies search path for application modules and modular JARs (replaces -cp / --class-path).
--module-source-path <path>N/AjavacSpecifies base directory containing multiple module source subdirectories.
--module <module>[/<mainclass>]-mjava, javacSpecifies the main module and optional main entry point class to execute or compile.
-d <dir>N/AjavacOutput destination directory for compiled .class files.
--module-version <ver>N/Ajar, javacEmbeds a version string (e.g., 2.1.0) into module-info.class.
--main-class <class>-ejarEmbeds the default application entry-point class into module-info.class.
--describe-module-djar, javaInspects and prints module descriptor metadata from a modular JAR or runtime module.
--list-modulesN/AjavaLists all observable platform and application modules.
--show-module-resolutionN/AjavaTraces step-by-step module graph resolution at startup.
--list-depsN/AjdepsAnalyzes and lists all modular dependencies for a class or JAR.
--jdk-internalsN/AjdepsScans for deprecated internal JDK APIs (e.g., sun.misc.*).

2. Compiling Modular Code with javac

Modular compilation with javac can operate in single-module mode or multi-module mode.

Single-Module Compilation

When compiling a single module whose source files are located under src/com.app:

# Compiling module descriptor and source files to destination output 'mods/com.app'
javac -d mods/com.app \
    src/com.app/module-info.java \
    src/com.app/com/app/Main.java \
    src/com.app/com/app/model/Order.java

Compiling Dependent Modules with --module-path (-p)

When compiling a module that depends on another pre-compiled module located in the mods directory:

javac -p mods \
    -d mods/com.client \
    src/com.client/module-info.java \
    src/com.client/com/client/Runner.java
  • The -p (or --module-path) flag tells javac where to locate compiled module artifacts (module-info.class files or modular JARs).
  • The -d flag specifies the target output directory for compiled class files.

Multi-Module Source Tree Compilation with --module-source-path

When multiple modules are developed in a single source tree, javac can compile all modules atomically in a single command using --module-source-path.

Directory Structure Requirement: Each module source subdirectory under the source root must exactly match the module name declared in its module-info.java.

project/
└── src/
    ├── com.app.core/
    │   ├── module-info.java
    │   └── com/app/core/CoreService.java
    └── com.app.client/
        ├── module-info.java
        └── com/app/client/Main.java
# Compiles all modules defined under src into their respective mods/<module-name> subdirectories
javac --module-source-path src -d mods $(find src -name "*.java")

# Or compile specific modules from the source tree:
javac --module-source-path src -d mods --module com.app.core,com.app.client

[!NOTE] During multi-module compilation, javac automatically determines the inter-module dependency order and compiles dependent modules in the correct sequence.


3. Packaging Modular JARs with jar

A Modular JAR is an archive that contains a compiled module-info.class in its root directory, alongside standard compiled class files and package directories.

1. Basic Modular JAR Creation

# Create directory for packaged JARs
mkdir -p mlib

# Package the compiled module into a modular JAR
jar --create --file mlib/com.app.core.jar -C mods/com.app.core .

2. Embedding Main Class and Module Version

The jar tool allows embedding metadata directly into module-info.class:

jar --create --file mlib/com.app.client-1.0.jar \
    --main-class com.app.client.Main \
    --module-version 1.0.0 \
    -C mods/com.app.client .
  • --main-class <fqcn> (or -e): Specifies the binary entry-point class.
  • --module-version <version>: Embeds a module version string into the descriptor.

3. Updating an Existing Modular JAR

jar --update --file mlib/com.app.client-1.0.jar \
    --main-class com.app.client.Main

4. Inspecting a Modular JAR with --describe-module

To verify the descriptor content of a packaged modular JAR:

jar --describe-module --file mlib/com.app.client-1.0.jar
# Or using short flags:
jar -d -f mlib/com.app.client-1.0.jar

Sample Output:

com.app.client@1.0.0 jar:file:.../mlib/com.app.client-1.0.jar!/module-info.class
exports com.app.client.api
requires com.app.core
requires java.base mandated
main-class com.app.client.Main

4. Running Modular Applications with java

The java launcher boots the Java Virtual Machine using the module path.

Execution Syntax Patterns

# Pattern 1: Full syntax with explicit module and main class
java --module-path mlib --module com.app.client/com.app.client.Main

# Pattern 2: Short flags (-p and -m)
java -p mlib -m com.app.client/com.app.client.Main

# Pattern 3: Short syntax when Main-Class is embedded in module-info.class
java -p mlib -m com.app.client

# Pattern 4: Passing application command-line arguments
java -p mlib -m com.app.client/com.app.client.Main arg1 arg2 --verbose

[!IMPORTANT] When executing via -m <module>/<mainclass>, the forward slash (/) separates the module name from the fully qualified class name. The separator is always a forward slash /, regardless of operating system (Windows, macOS, Linux). Never use colons, semicolons, or dots as the module-to-class separator.


5. Diagnostic and Migration Flags

When running modular applications or troubleshooting migration issues, the java launcher offers specialized flags:

  • --show-module-resolution: Logs the module resolution process step-by-step during JVM startup, showing root modules, required modules, and resolved bindings.
  • --list-modules: Prints all modules observable by the runtime (built-in platform modules and modules found on the module path).
  • --add-modules <module-list>: Explicitly adds root modules to the default root set for module graph resolution (vital when running tests or loading optional modules).
  • --add-exports <module>/<package>=<target-module>: Patches a module at runtime to export an internal package, breaking encapsulation for legacy migration.
  • --add-opens <module>/<package>=<target-module>: Patches a module at runtime to open an internal package for deep reflection.

6. Dependency Diagnostics with jdeps

The jdeps tool analyzes static byte-code references in class files and JAR archives to discover required modules and detect illegal API usage.

# High-level module dependency summary
jdeps --summary -p mlib mlib/com.app.client-1.0.jar
# Output:
# com.app.client -> com.app.core
# com.app.client -> java.base

# List all required platform and application modules
jdeps --list-deps mlib/com.app.client-1.0.jar

# Check module descriptor for unused dependencies or missing requires
jdeps --check com.app.client -p mlib mlib/com.app.client-1.0.jar

# Scan legacy code for usage of deprecated internal JDK APIs
jdeps --jdk-internals legacy-app.jar

Understanding jdeps --jdk-internals Output

When migrating legacy libraries, jdeps --jdk-internals flags problematic classes and suggests standard replacement APIs:

legacy-app.jar -> jdk.unsupported
   com.legacy.crypto.CipherUtil -> sun.misc.BASE64Encoder     JDK internal API (JDK removed / encapsulated)
   Suggested replacement: Use java.util.Base64
Loading diagram...
Modular Build, Packaging, and CLI Execution Workflow
Test Your Knowledge

A developer needs to compile two interdependent modules (com.app and com.util) organized in a source directory tree where source files are located at src/com.app/module-info.java and src/com.util/module-info.java. Which javac command properly compiles both modules into the mods destination directory?

A
B
C
D
Test Your Knowledge

A modular JAR is packaged using the command: jar --create --file mlib/orders.jar --main-class com.orders.Main -C mods/com.orders .. Which command properly runs this application using the packaged entry point?

A
B
C
D
Test Your Knowledge

Which of the following CLI commands correctly launches a modular Java application named com.analytics with entry point class com.analytics.app.Runner located on module path dist?

A
B
C
D
Test Your Knowledge

Which JDK command-line tool is specifically designed to perform static bytecode dependency analysis, discover required modules, and detect deprecated internal JDK APIs?

A
B
C
D