So far, we have simply compiled modules into the directory tree of the source code. Clearly, that is not satisfactory for deployment. Instead, a module can be deployed by placing all its classes in a JAR file, with a modute-info.ctass in the root. Such a JAR file is called a modular JAR.
To create a modular JAR file, use the jar tool in the usual way. If you have multiple packages, it is best to compile with the -d option which places class files into a separate directory. The directory is created if it doesn’t already exists. Then use the -C option of the jar command to change to that directory when collecting files.
javac -d modutes/com.horstmann.greet $(find com.horstmann.greet -name *.java)
jar -cvf com.horstmann.greet.jar -C modutes/com.horstmann.greet .
If you use a build tool such as Maven, Ant, or Gradle, just keep building your JAR file as you always do. As long as modute-info.ctass is included, you get a modular JAR.
Then, include the modular JAR in the module path, and the module will be loaded.
As with regular JAR files, you can specify a main class in a modular JAR:
javac -p com.horstmann.greet.jar \
-d modutes/v2ch09.exportedpkg $(find v2ch09.exportedpkg -name *.java)
jar -c -v -f v2ch09.exportedpkg.jar -e com.horstmann.hello.HelloWorld \
-C modules/v2ch09.exportedpkg .
When you launch the program, you specify the module containing the main class:
java -p com.horstmann.greet.jar:v2ch09.exportedpkg.jar -m v2ch09.exportedpkg
When creating a JAR file, you can optionally specify a version number. Use the –module-version parameter, and also add @ and the version number to the JAR file name:
jar -c -v -f com.horstmann.greet@1.0.jar –module-version 1.0 -C com.horstmann.greet .
As already discussed, the version number is not used by the Java Platform Module System for resolving modules, but it can be queried by other tools and frameworks.
Source: Horstmann Cay S. (2019), Core Java. Volume II – Advanced Features, Pearson; 11th edition.