从Java9开始,jdk默认不提供jre,因为Java本身的文件系统已发送重大变化,在“包”之上多了“模块”的概念,我们可以(在某种意义上必须)根据自己编写的模块需要,自行组织需要的运行时环境。
Java打包的文件格式分为以下3种:
1、jar 传统的打包文件,必须运行在庞大的jre下;
2、jmod jmod格式也是基于zip压缩,其可以包含jar格式不能包含的类型文件,但其和jar格式的区别是,其中的文件不能被执行,仅能用于编译时和Link-Time,原话是:This means this files contained in JMOD can be used only at compile-time or link-time, but not at runtime。
3、jimage 为jvm执行而优化过的格式,可使用jlink生成,它自包含了运行时。
(参考 http://ju.outofmemory.cn/entry/367986)
使用jlink打包包含运行时的镜像步骤:
1、编译源代码和根目录下的模块声明文件module-info.java
javac -d out --module-path out test/Test.java
(此处--module-path out参数去掉也可正常编译)
javac -d out module-info.java
2、使用jlink打包文件:
jlink --launcher run=jlinkModule/test.Test --module-path "%JAVA_HOME%\jmods"; ./ --add-modules jlinkModule --output package
↓ ↓ ↓ ↓ ↓
是否在bin目录下 需要打包的运行时 字节码文件根目录 需要打包的模块 输出文件夹
生成一个可执行的脚本 当打包到不同环境时,
可选择不同运行时(如
Linux下的jmod)
生成的window脚本在执行完程序后会自动退出,若想维持窗口可在脚本后加入pause命令
以上步骤仅限于基于模块化开发的项目,而对于目前的Maven项目而言,jlink无法直接处理那些未模块化的依赖,但我们可以手动找出那些依赖所依赖的JDK模块再使用Jlink创建运行时
例如:Spring boot本身内嵌的Maven打包脚本在编译项目时会自动地将项目所需依赖全都以jar格式打包在项目文件内,这些依赖无需我们处理
通过这些jar包,我们就能使用jdeps命令找出项目的所依赖的jdk模块,之后再按之前步骤打包即可
具体步骤:
1、找出每个项目依赖的jar包所依赖的jdk模块:
将lib目录中的jar包全部解压缩出来,在lib文件夹下直接执行,获取依赖清单(去重)
jdeps --list-deps *.jar
2、将这些模块直接打包,创建一个仅包含项目所需jdk模块的运行时镜像
jlink --no-header-files --no-man-pages --compress=2 --strip-debug --module-path "C:\Program Files\Java\jdk-12.0.1\jmods" --add-modules java.datatransfer,java.desktop,java.logging,java.management,java.naming,java.rmi,java.scripting,java.sql,java.transaction.xa,java.xml,jdk.jsobject,jdk.unsupported,jdk.unsupported.desktop,jdk.xml.dom --output out
无头文件 无手册 压缩等级 运行时的模块路径(win或linux) 运行时包含模块
此处需要注意命令中不能含有空格,如需使用包含空格的变量要使用引号包裹他们
3、此时我们以获得了一个包含自定义JDK模块的运行时镜像,可以使用打包生成的文件夹的bin目录下的java.exe(或linux环境下的java)来运行项目jar文件