Memra

Building & running modular apps

Directory layout, javac --module-source-path, java -m, modular jars, and module-path vs classpath.

Source layout

Convention: one directory per module under a common root, each containing its module-info.java at its own source root:

src/
  com.acme.app/
    module-info.java
    com/acme/app/Main.java
  com.acme.lib/
    module-info.java
    com/acme/lib/Util.java

Compiling multiple modules

javac --module-source-path src \
      -d out \
      $(find src -name "*.java")

--module-source-path tells javac the root where module directories live. Compiled classes land in out/com.acme.app/ etc., preserving the module structure.

Running a modular app

java --module-path out \
     --module com.acme.app/com.acme.app.Main

--module-path (alias -p) is the module equivalent of --class-path. The -m / --module flag specifies <module>/<main-class>.

Modular jars

Package each module into its own jar. The --main-class and --module-version attributes can be embedded:

jar --create \
    --file mods/com.acme.app.jar \
    --main-class com.acme.app.Main \
    --module-version 1.0 \
    -C out/com.acme.app .

Once jarred, launch with:

java --module-path mods -m com.acme.app

module-path vs classpath

| | --class-path | --module-path | |---|---|---| | Encapsulation | None | Strong (exports only) | | Dependency check | Runtime | Compile + runtime | | Missing module | ClassNotFoundException at runtime | Detected at startup | | Type | unnamed module | named or automatic module |

You can mix both flags — common during migration — but named modules cannot explicitly require the unnamed module (the unnamed module is a catch-all, not a first-class citizen).

NORMAL ~/memra/learn/java-from-zero/building-modular-apps utf-8 LF