项目结构

m1
  |-src
    |-module-info.java
    |-com
      |-m1
        |-M1App.java

其中 module-info.java 文件描述模块的依赖以及暴露给外部模块的信息

com.m1.M1App.java

package com.m1;

public class M1App {
    public static void main(String[] args) {
        System.out.println("this is m1");
    }
}

module-info.java

module com.m1 {
  requires java.base;
  exports com.m1;
}

语法说明:

  • requires:指这个模块需要依赖哪些外部模块

  • exports:指这个模块要将自己的哪些包暴露出去给其他模块使用,注意,不支持在一个 exports 里同时将一个包下的所有子包也暴露,也就是说,一行 exports,只能暴露一个包下的直接类,子包里面的类不会被暴露

编译

进入 m1 目录执行

javac --module-path ./ -d out src/module-info.java src/com/m1/*.java

结果会在 m1 目录下新建一个 out 目录,里面就是编译好的 class 文件

参数说明:

  • --module-path:指定模块路径

  • -d:指定输出目录

  • 最后跟着的是要编译的 .java 文件

将模块打包成 jar

还是在 m1 目录下执行

jar --create --file=m1.jar --main-class=com.m1.M1App -C ./out ./

结果会在 m1 目录下生成 m1.jar

参数说明:

  • --create:指要创建 jar 文件

  • --file:指定生成后的 jar 文件名

  • --main-class:指定该 jar 的入口主类

运行模块

还是在 m1 目录下执行

java --module-path ./m1.jar --module com.m1/com.m1.M1App

参数说明:

  • --module-path:模块 jar 的路径

  • --module:指定要执行哪个模块中的哪个类,格式是 模块名/类全限定名

将模块打包成最小镜像

还是在 m1 目录下执行

jlink --module-path ./m1.jar --add-modules com.m1 --output ./m1-image

结果会在 m1 目录下生成 m1-image 目录,里面包含了运行这个模块的最小运行时

参数说明:

  • --module-path:模块路径,可以是 jar 包路径,也可以是 .class 文件的目录(比如本例的 ./out 目录)

  • --add-modules:指定要添加的模块名

  • --output:输出到哪

运行打包好的最小镜像

还是在 m1 目录下执行

./m1-image/bin/java -m com.m1/com.m1.M1App

./m1-image 就是上面生成的最小镜像的目录,它有运行时所需的 jre 以及需要依赖的依赖库等等

./m1-image/bin/java 就是用镜像内的 jvm 来启动,因为我们的 com.m1 模块已经一起打包进来了,所以可以用 -m 参数指定要运行的模块

参数说明:

  • -m:指定要运行哪个模块的哪个类,格式是 模块名/类全限定名