從Java9開(kāi)始,jdk默認(rèn)不提供jre片迅,因?yàn)镴ava本身的文件系統(tǒng)已發(fā)送重大變化抽高,在“包”之上多了“模塊”的概念,我們可以(在某種意義上必須)根據(jù)自己編寫的模塊需要跛梗,自行組織需要的運(yùn)行時(shí)環(huán)境寻馏。
Java打包的文件格式分為以下3種:
1、jar 傳統(tǒng)的打包文件核偿,必須運(yùn)行在龐大的jre下诚欠;
2、jmod jmod格式也是基于zip壓縮漾岳,其可以包含jar格式不能包含的類型文件轰绵,但其和jar格式的區(qū)別是,其中的文件不能被執(zhí)行尼荆,僅能用于編譯時(shí)和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執(zhí)行而優(yōu)化過(guò)的格式液样,可使用jlink生成振亮,它自包含了運(yùn)行時(shí)。
(參考 http://ju.outofmemory.cn/entry/367986)
使用jlink打包包含運(yùn)行時(shí)的鏡像步驟:
1鞭莽、編譯源代碼和根目錄下的模塊聲明文件module-info.java
javac -d out --module-path out test/Test.java
(此處--module-path out參數(shù)去掉也可正常編譯)
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目錄下 需要打包的運(yùn)行時(shí) 字節(jié)碼文件根目錄 需要打包的模塊 輸出文件夾
生成一個(gè)可執(zhí)行的腳本 當(dāng)打包到不同環(huán)境時(shí),
可選擇不同運(yùn)行時(shí)(如
Linux下的jmod)
生成的window腳本在執(zhí)行完程序后會(huì)自動(dòng)退出澎怒,若想維持窗口可在腳本后加入pause命令
以上步驟僅限于基于模塊化開(kāi)發(fā)的項(xiàng)目褒搔,而對(duì)于目前的Maven項(xiàng)目而言,jlink無(wú)法直接處理那些未模塊化的依賴丹拯,但我們可以手動(dòng)找出那些依賴所依賴的JDK模塊再使用Jlink創(chuàng)建運(yùn)行時(shí)
例如:Spring boot本身內(nèi)嵌的Maven打包腳本在編譯項(xiàng)目時(shí)會(huì)自動(dòng)地將項(xiàng)目所需依賴全都以jar格式打包在項(xiàng)目文件內(nèi)站超,這些依賴無(wú)需我們處理
通過(guò)這些jar包荸恕,我們就能使用jdeps命令找出項(xiàng)目的所依賴的jdk模塊乖酬,之后再按之前步驟打包即可
具體步驟:
1、找出每個(gè)項(xiàng)目依賴的jar包所依賴的jdk模塊:
將lib目錄中的jar包全部解壓縮出來(lái)融求,在lib文件夾下直接執(zhí)行咬像,獲取依賴清單(去重)
jdeps --list-deps *.jar
2、將這些模塊直接打包生宛,創(chuàng)建一個(gè)僅包含項(xiàng)目所需jdk模塊的運(yùn)行時(shí)鏡像
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
無(wú)頭文件 無(wú)手冊(cè) 壓縮等級(jí) 運(yùn)行時(shí)的模塊路徑(win或linux) 運(yùn)行時(shí)包含模塊
此處需要注意命令中不能含有空格县昂,如需使用包含空格的變量要使用引號(hào)包裹他們
3、此時(shí)我們以獲得了一個(gè)包含自定義JDK模塊的運(yùn)行時(shí)鏡像陷舅,可以使用打包生成的文件夾的bin目錄下的java.exe(或linux環(huán)境下的java)來(lái)運(yùn)行項(xiàng)目jar文件