1、准备
lib
mods
src/cn.gbase.hellomodule
src/cn.gbase.hellomodule/module-info.java
src/cn.gbase.hellomodule/cn/gbase/hellomodule/Welcome.java
//module-info.java module cn.gbase.hellomodule { }
package cn.gbasae.hellomodule; public class Welcome { public static void main(String[] args) { System.out.println("hello module in jdk9"); Classcls = Welcome.class; Module mod = cls.getModule(); String moduleName = mod.getName(); System.out.format("Module Name: %s%n", moduleName); } }
2、编译
javac -d mods/cn.gbase.hellomodule --module-version 1.0 src/cn.gbase.hellomodule/module-info.java src/cn.gbase.hellomodule/cn/gbase/hellomodule/*
编译结果
mods/cn.gbase.hellomodule/cn/gbasae/hellomodule/Welcome.class mods/cn.gbase.hellomodule/module-info.class
bogon:testModules rachelluo$ javap mods/cn.gbase.hellomodule/module-info.class Compiled from "module-info.java" module [email protected] { requires java.base; }
在JDK 9中增强了jar工具。它允许在创建模块化JAR时指定模块版本。
javac -d mods --module-source-path src $(find src -name "*.java")
3、打包
jar --create --file lib/cn.gbase.hellomodule-1.0.jar --main-class cn.gbase.hellomodule.Welcome --module-version 1.0 -C mods/cn.gbase.hellomodule .
bogon:testModules rachelluo$ ll lib
total 8
-rw-r--r-- 1 rachelluo staff 1587 10 3 20:42 cn.gbase.hellomodule-1.0.jar
bogon:testModules rachelluo$ java --module-path lib --list-modules cn.gbase.hellomodule
......
[email protected] file:///Users/rachelluo/Documents/workspace/testModules/lib/cn.gbase.hellomodule-1.0.jar
-
--create
选项表示要创建一个新的模块化JAR。 -
--file
选项用于指定新的模块化JAR的位置和名称。将新的模块化JAR保存在lib目录中,其名称将为cn.gbase.hellomodule1.0.jar。将模块化JAR的版本指定为1.0。 -
--main-class
选项指定public static void main(String[])
方法作为应用程序入口。当您指定此选项时,jar工具将在module-info.class文件中添加一个属性,其值是指定类的名称。 jar工具还使用此选项将Main-Class属性添加到MANIFEST.MF文件中。 -
--module-version
选项将模块的版本指定为1.0。 jar工具将把这些信息记录在module-info.class文件的属性中。请注意,将模块版本指定为1.0不会影响模块化JAR的名称。包含1.0以指示其文件名的版本。该模块的实际版本由此选项指定。 -
-C
选项用于指定执行jar命令时将用作设置当前目录。将mods\cn.gbase.hellomodule目录指定为jar工具的当前目录。这将使jar工具从该目录中读取所有要包含在模块化JAR中的文件。 - 命令的最后一部分是一个点(.),这意味着jar工具需要包括当前目录mods\cn.gbase.hellomodule下所有文件和目录。请注意,这个参数和
-C
选项一起使用。
4、运行
java --module-path--module /
bogon:testModules rachelluo$ java --module-path lib --module cn.gbase.hellomodule/cn.gbase.hellomodule.Welcome hello module in jdk9 Module Name: cn.gbase.hellomodule bogon:testModules rachelluo$
如果在模块代码打包到模块化JAR中时指定主类,则可以从命令中省略主类名称
bogon:testModules rachelluo$ java --module-path lib --module cn.gbase.hellomodule hello module in jdk9 Module Name: cn.gbase.hellomodule bogon:testModules rachelluo$
还可以指定包含模块代码的目录作为模块路径。 已将模块代码编译到mods目录中
bogon:testModules rachelluo$ java --module-path mods --module cn.gbase.hellomodule/cn.gbase.hellomodule.Welcome hello module in jdk9 Module Name: cn.gbase.hellomodule
JDK还提供了-jar
选项来从JAR文件运行主类
bogon:testModules rachelluo$ java -jar lib/cn.gbase.hellomodule-1.0.jar hello module in jdk9 Module Name: null bogon:testModules rachelluo$ java --class-path lib/cn.gbase.hellomodule-1.0.jar cn.gbase.hellomodule.Welcome hello module in jdk9 Module Name: null
看来只有输出中的第一行是正确的,第二行是不正确的。 它找到了
main()
方法中执行了代码。 它正确打印消息,但模块名称为空。
需要了解JDK 9中java命令的行为。-jar
选项存在于JDK 9之前。在JDK 9中,类型作为模块的一部分,可以通过模块路径或类路径加载。如果通过类路径加载类型,则该类型成为未命名模块的成员。该类型从其原始模块中失去其成员资格,即使该类型是从模块化JAR加载的。实际上,如果一个模块化的JAR放置在类路径上,那么它被视为一个JAR(而不是一个模块化的JAR),忽略它的module-info.class文件。每个应用程序类加载器都有一个未命名的模块。类加载器从类路径加载的所有类型都是该类加载器的未命名模块的成员。一个未命名的模块也被表示为一个Module类的实例,该类的getName()
方法返回null。