解鎖Java打包新姿勢

在平時我們打包會將其打成Jar,那麼在其他平臺運行的時候就需要安裝jre來支持運行。

那麼實際上Java是可以打包成native平臺所屬類型的,例如:

  • exe
  • installer
  • image
  • msi
  • dmg
  • rpm
  • deb

當然我在查閱了很多博客,及其官網的信息,

見到最多的是exe4j,但是看到有一些評論說,打包之後無法運行,而且我下載了exe4j之後是不能運行的。所以排除此選項。

除了exe4j呢還有,install4j,jwrapper等工具,但是他們都是收費的,所以也排除。

還有Java9的jaot,早期版本的java14的jpackage,java8的javapackager

在查閱的博客中有人提到了java9的jaot,下載了java9,但是並沒有找到jaot,考慮到常用版本是8,所以也排除了jaot

那麼只剩下java14的jpackage和java8的javapackager,這兩個我都有過實踐,效果幾乎一直,打出來的包大小也差不多(沒有對jre做過任何裁剪的情況下)。

最終選擇了Java8自帶的javapackager這個工具。(但是遺憾的是,無法顯示控制檯的內容,建議使用日誌文件去代替。java14的jpackage是可以指定是否顯示控制檯)

現在我們就來看看,如何將jar包打包成native形式的包。

準備內容

  • Inno Setup Compiler(Java8支持6版本以下的,不要下載6及其6以上的版本,否則無法打包成功)

  • wix(打包成msi必須下載,沒有下載javapackager會提示缺少wix)

  • java8的環境

  • 示例的jar程序(本文使用這個jar作爲示例,方便交流學習)

    程序介紹

    啓動程序之後,會在c盤創建一個名爲我是測試文件.txt的文件,每秒會給文件中寫入”休眠*秒“的字樣,直到10s之後程序運行結束,結尾會有寫入成功的字樣。(如果啓動之後沒有生成該文件,請在任務管理器找到該進程結束,然後以管理員身份運行該程序。)

讓我們開始第一個打包吧!

在此之前,默認您準備內容已經閱讀並且完成了。

  1. 進入你下載jar的包的文件夾,並且打開powershell

  2. 輸入:

    javapackager -deploy -native image  -outdir cs -outfile cs -srcfiles pack.jar -appclass cn.qs.CS -name CS
    
  3. 你會在同級目錄找到一個叫cs的文件夾,進入cs,再進入bundles文件夾。找到cs.exe,用管理員身份運行。

  4. 進入C盤就能找到該程序生成的我是測試文件.txt的文件

至此,簡單的打包結束。

現在我們來看一下上面的命令代表什麼意思。

javapackager---java8自帶的打包程序

-deploy---用來構建目標機器的發行版本,簡單說就是打包成exe或者其他平臺的包,如果不帶任何參數,會生成一個基本的應用程序,不建議不帶任何參數

-native image---爲jar創建磁盤鏡像(可以將image替換爲其他的類型,例如exe,msi,deb,rpm)

-outdir cs---輸出目錄。

-outfile cs----輸出文件(不要帶後綴,比如cs.exe,就寫cs就行了)。

-srcfiles pack.jar---要打包的jar文件。

-appclass cn.qs.CS---jar文件的主類的全限定名。(注意是全限定名)

-name CS---啓動之後的應用名稱

更多的參數將會在文章最後附上。也可以直接輸入javapackager來查看幫助,或者進入官網查看

來做一些定製吧

目標

  1. 修改應用圖標
  2. 修改應用說明(按照官網操作,指定了但是無效,可以忽略)
  3. 修改應用程序的供應商(vendor)

注意:因爲是控制檯程序呢,所以 標題,寬,高指定的話也沒什麼意義。所以我們在此就修改這兩個屬性就可以了。

我們開始定製吧

注意:測試過image的形式,描述(description)和說明(vendor)是無效的,在exe和msi形式下是可以的

  1. 在下載的jar的同級目錄,刪掉剛纔生成的cs文件夾。

  2. 重新執行命令:

    javapackager -deploy -native exe  -outdir cs -outfile cs -srcfiles pack.jar -appclass cn.qs.CS -name CS -description "測試的描述" -vendor "測試廠商" -Bicon=".\cs.ico"
    
  3. 現在我們就定義成功了。(可以自行看一下,是不是我們自定義的圖標,說明,供應商)
    關於更多自定義的話請查閱官網(這些自定義的bundle參數在使用的時候要注意,-B加上參數名=值 例如 icon 使用的時候就是 -Bicon=“path”)

bundle參數說明

除了上述打包bundle參數之外呢,在介紹一些通用的bundle參數和windows的bubdle參數。

通用參數

  1. appVersion=version
    應用的版本,例如:-BappVersion=1.0.1
  2. classPath=path
    類路徑相對於打包後應用的目錄(默認不用設置。)
  3. icon=path
    應用圖標的路徑,例如:-Bicon=".\cs.ico"
  4. identifier
    用於其他特定平臺的默認值。
  5. jvmOptions=option
    用來指定jvm參數,例如:-BjvmOptions=-Xmx128m -BjvmOptions=-Xms128m
  6. jvmProperties=property=value
    當程序運行的時候,這個參數會被傳入到jvm中,可以通過System.getProperty()來獲取,java -Dproperty 都可以使用,需要指定參數名和值,如果要傳遞多個請參考:-BjvmProperties=apiUserName=example -BjvmProperties=apiKey=abcdef1234567890
  7. mainJar=filename
    包含主類的jar文件的名稱,該文件名通常是從jar文件的mainfest中獲得,如果你使用javapackager命令,不用指定這個值
  8. preferencesID=node
    用來檢查用戶可覆蓋的jvm選項,被指定的選項在運行時作爲 -Dapp.preferences.id.參數傳給應用,這個參數需要和userJVMOptions一起使用。
  9. runtime=path
    Jdk或者jre的位置,如果使用系統默認的jre則不需要提供。例如:-Bruntime=
  10. userJvmOptions=option=value
    能被用戶覆蓋的jvm選項 java命令所使用的任何選項都是有效的,要傳入多個,請參考:
    -BuserJvmOptions=-Xmx=128m -BuserJvmOptions=-Xms=128m

windows

  1. copyright=string
    應用的版本字符串,例如:2002-2020 Jetbrains s.r.o.

  2. licenseFile=path
    最終用戶許可協議的位置(EULA),例如 -BlicenseFile=COPYING

  3. menuHit=boolean

    標誌着是否在開始菜單或開始屏幕上安裝快捷方式,設置爲true來安裝快捷方式,默認是true 例如:-BmenuHint=true

  4. shortcutHint=boolean
    標誌着是否在桌面安裝快捷圖標,設置爲true表示安裝,默認是false。例如:-BshortcutHint=true

  5. systemWide=boolean
    標誌着應用程序是安裝在Programs Files中還是在UserData中,設置爲true安裝在Programs Files,默認爲false

  6. win.menuGroup=group
    menuGroup只有在menuHint爲true的時候才生效,menuHint爲false這個參數會被忽略掉。

  7. vendor=value
    也就是作者,可以是個人,組織,公司等。用於exe,或者registry metadata.

參數簡述

用法: javapackager -command [-options]

其中 command 爲以下項之一:
  -createjar
          打包程序根據其他參數生成 jar 檔案。
  -deploy
          打包程序根據其他參數生成 jnlp 和 html
          文件。
  -createbss
          將 css 文件轉換爲二進制形式
  -signJar
          使用提供的證書爲 jar 文件簽名。
  -makeall
          將 compilation, createjar 和 deploy 步驟作爲一個調用執行,
          在其中預定義大多數參數。源必須位於 "src"
          文件夾中, 生成的文件 (jar, jnlp, html) 將放入 "dist"
          文件夾中。此命令只能以最簡單方式配置, 並且
          儘可能自動進行。

createjar 命令的選項包括:
  -appclass <application class>
          要執行的應用程序類的限定名稱。
  -preloader <preloader class>
          要執行的預加載器類的限定名稱。
  -paramfile <file>
          包含默認命名應用程序參數的屬性文件。
  -argument arg
          JNLP 文件的 <fx:argument> 元素中要放入的未命名
          參數。
  -classpath <files>
          相關 jar 文件名列表。
  -manifestAttrs <manifest attributes>
          附加清單屬性列表。語法: "name1=value1,
          name2=value2,name3=value3"。
  -noembedlauncher
          如果存在, 打包程序將不會向 jarfile 添加 JavaFX
          啓動程序類。
  -nocss2bin
          在複製到 jar 之前, 打包程序不會將 CSS 文件轉換爲
          二進制形式。
  -runtimeversion <version>
          所需 JavaFX 運行時的版本。
  -outdir <dir>
          要將輸出文件生成到的目錄的名稱。
  -outfile <filename>
          生成的文件的名稱 (不帶擴展名)。
  -srcdir <dir>
          待打包文件的基目錄。
  -srcfiles <files>
          srcdir 中的文件的列表。如果省略, 將對 srcdir (在
          這種情況下是必需的參數) 中的所有文件進行打包。

deploy 命令的選項包括:
  -title <title>
          應用程序的標題。
  -vendor <vendor>
          應用程序的供應商。
  -description <description>
          應用程序的說明。
  -appclass <application class>
          要執行的應用程序類的限定名稱。
  -preloader <preloader class>
          要執行的預加載器類的限定名稱。
  -paramfile <file>
          包含默認命名應用程序參數的屬性文件。
  -htmlparamfile <file>
          包含所生成小應用程序參數的屬性文件。
  -width <width>
          應用程序的寬度。
  -height <height>
          應用程序的高度。
  -native <type>
          生成自包含的應用程序包 (如果可能)。
          如果指定了類型, 則只創建此類型的包。
          所支持類型的列表包括: installer, image, exe, msi, dmg, rpm 和 deb。
  -name <name>
          應用程序的名稱。
  -embedjnlp
          如果存在, 會將 jnlp 文件嵌入 html 文檔中。
  -embedCertificates
          如果存在, 會將證書嵌入 jnlp 文件中。
  -allpermissions
          如果存在, 應用程序將需要 jnlp 文件中的所有
          安全權限。
  -updatemode <updatemode>
          設置 jnlp 文件的更新模式。
  -isExtension
          如果存在, srcfile 將被視爲擴展。
  -callbacks
          在生成的 HTML 中指定用戶回調方法。格式爲
          "name1:value1,name2:value2,..."
  -templateInFilename
          html 模板文件的名稱。佔位符格式爲
          #XXXX.YYYY(APPID)#
  -templateOutFilename
          要將已填充的模板寫入到的 html 文件的名稱。
  -templateId
          用於模板處理的應用程序的應用程序 ID。
  -argument arg
          JNLP 文件的 <fx:argument> 元素中要放入的未命名
          參數。
  -outdir <dir>
          要將輸出文件生成到的目錄的名稱。
  -outfile <filename>
          生成的文件的名稱 (不帶擴展名)。
  -srcdir <dir>
          待打包文件的基目錄。
  -srcfiles <files>
          srcdir 中的文件的列表。如果省略, 將對 srcdir (在
          這種情況下是必需的參數) 中的所有文件進行打包。

createbss 命令的選項包括:
  -outdir <dir>
          要將輸出文件生成到的目錄的名稱。
  -srcdir <dir>
          待打包文件的基目錄。
  -srcfiles <files>
          srcdir 中的文件的列表。如果省略, 將對 srcdir (在
          這種情況下是必需的參數) 中的所有文件進行打包。

signJar 命令的選項包括:
  -keyStore <file>
          密鑰庫文件名。
  -alias
          密鑰的別名。
  -storePass
          用於檢查密鑰庫完整性或對密鑰庫取消鎖定的口令。
  -keyPass
          用於恢復密鑰的口令。
  -storeType
          密鑰庫類型, 默認值爲 "jks"。
  -outdir <dir>
          要將輸出文件生成到的目錄的名稱。
  -srcdir <dir>
          待簽名文件的基目錄。
  -srcfiles <files>
          srcdir 中的文件的列表。如果省略, 將對 srcdir (在
          這種情況下是必需的參數) 中的所有文件進行打包。

makeAll 命令的選項包括:
  -appclass <application class>
          要執行的應用程序類的限定名稱。
  -preloader <preloader class>
          要執行的預加載器類的限定名稱。
  -classpath <files>
          相關 jar 文件名列表。
  -name <name>
          應用程序的名稱。
  -width <width>
          應用程序的寬度。
  -height <height>
          應用程序的高度。
  -v      啓用詳細輸出。

示例用法:
--------------
javapackager -createjar -appclass package.ClassName
  -srcdir classes -outdir out -outfile outjar -v
          將類目錄的內容打包到 outjar.jar,
          將應用程序類設置爲 package.ClassName。
javapackager -deploy -outdir outdir -outfile outfile -width 34 -height 43
  -name AppName -appclass package.ClassName -v -srcdir compiled
          在由 package.ClassName 類啓動且大小爲 34x43 的
          應用程序 AppName 的 outdir 中生成
          outfile.jnlp 和對應的 outfile.html 文件。
javapackager -makeall -appclass brickbreaker.Main -name BrickBreaker
  -width 600 -height 600
          此命令執行包含編譯在內的所有打包工作:
          compile, createjar 和 deploy。

結語

經過這一番操作,其實應該對打包有一定的個人理解了。

也有的人提出創建一個bat來啓動java程序,好處不言而喻,但是也有弊端。例如:在任務管理器裏面顯示的進程是java進程,那麼如果有多個這樣的程序呢,就會導致分不清進程。而且需要依賴JRE。

那麼在這種打包方式中呢,存在很多弊端,例如,包體積太大,但是解決了上面的弊端問題,而且在java9中可以使用jlink來對jre進行裁剪,包體積會進一步縮小,個人更傾向於第二種打包方式,如何抉擇,請結合業務場景和需求。

關於javapackager打包相關的內容,請參考官網

遇到問題,請在下方評論留言。

發佈了48 篇原創文章 · 獲贊 16 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章