Bundle a minimal JRE into an exe using Launch4j and Jlink

Mon, Jul 26, 2021 閱讀時間 1 分鐘

在Windows環境想要發布開發好的Java應用程序給別人使用,可以利用Launch4j轉換成exe檔方便執行,Launch4j會產生一個原生啟動程序,實際上還是依賴Java的執行環境來運行程式,另外一方面可以再透過Jlink生成自定義的JRE來縮小整體的體積,從JDK 9開始架構模組化了,不再提供默認的JRE,但還是能自己用提供的jlink工具程式來創建

Launch4j

範例目錄結構(GitHub)

C:\swing-demo-l4j
|-- jre
|   |-- bin
|   |-- conf
|   |-- legal
|   |-- lib
|   `-- release
|-- lib
|   `-- swing-demo.jar
|-- build.xml
|-- icon.ico
`-- swing-demo.exe

6 directories, 5 files

Basic頁籤

  • Output file:指定要輸出的執行檔名
  • Jar runtime path:這裡勾選不把jar包進exe,只要能夠在exe運行時找的到就可以
  • Icon:在執行檔可以加上個人化的圖示,exe編譯時就會用到,所以用絕對路徑直接指定

Classpath頁籤

  • Main class:指定要執行的main method所在的class
  • Classpath:這裡用wildcard讓exe運行時動態解析lib目錄下的所有jar檔加入到JVM

JRE頁籤

  • Bundled JRE paths:指定相對於exe的jre路徑,使用64位元的就勾起來
  • Min JRE version:如果發布程式沒有要自帶JRE,可以輸入最低需求版本會從系統環境中去搜尋

最後配置完成先保存為xml,接著按下齒輪編譯產生出我們要的exe檔

以前還在java 8的時候,可能開發幾十KB的程式要給其他人用,如果對方沒有安裝java執行環境,就要把自己的jre複製一份和程式一起提供就變成上百MB了,好在現在用java 11可以根據自己程式實際有用到的java模組來客製生成jre,因為我們並不總是需要一個完整的jre吧,這樣就能大幅的縮小了體積,整個就精簡多了

OpenJDK 11 (LTS): jdk-11.0.11+9

C:\java\jdk-11.0.11+9
|-- bin
|-- conf
|-- include
|-- jmods
|-- legal
|-- lib
`-- release

6 directories, 1 file

bin\jdeps.exe --print-module-deps C:\swing-demo-l4j\lib\*.jar

先用jdeps工具幫助我們分析出程式在執行時依賴的java模組,輸出結果後面可用於jlink

bin\jlink.exe --module-path jmods --add-modules java.base,java.desktop --strip-debug --compress=2 --no-header-files --no-man-pages --output jre

接著使用jlink命令就能創建出精簡版的jre,並且可以再配合一些參數選項進一步減少產生的大小

  • module-path:指定位於jdk目錄下的java模組位置
  • add-modules:加入需要的模組,多個用逗號隔開,把前一步jdeps分析的結果貼過來
  • output:要生成jre的資料夾路徑

最後發布出去的結果就會像是這樣
Try it yourself