可以直接執(zhí)行運(yùn)行的java應(yīng)用
背景
以前還在上學(xué)的時(shí)候我有試用過(guò)exe4j,這個(gè)工具可以把一個(gè)可執(zhí)行的jar文件做成一個(gè)exe文件,甚至還能制作成安裝包,像普通的軟件一樣安裝卸載。如果是java桌面應(yīng)用那么exe4j肯定是很實(shí)用的工具了,但是由于java那難用且難看的gui組件,用java做的桌面應(yīng)用相對(duì)較少,java更多是活躍在web服務(wù)端、后端等領(lǐng)域。
spring-boot
早幾年的java web應(yīng)用都是打包成一個(gè)war,丟到tomcat中去運(yùn)行,這幾年spring boot火起來(lái)之后,應(yīng)用打包后就是一個(gè)可以直接java -jar運(yùn)行的jar文件了,只要服務(wù)器上安裝了java,就能直接運(yùn)行起來(lái)。spring-boot曾經(jīng)做了一個(gè)這樣的功能:在給spring-boot-plugin添加了executable=true的配置后,給jar文件添加可執(zhí)行的權(quán)限,那么它就可以像shell腳本一樣可以直接運(yùn)行,如下所示:



原理和優(yōu)點(diǎn)本文就不詳細(xì)說(shuō)明了,可以查看spring-boot官方文檔來(lái)了解。
缺點(diǎn)是只支持linux系統(tǒng),沒(méi)辦法,誰(shuí)讓現(xiàn)在的服務(wù)器大多是linux呢?
graalvm
graalvm也是甲骨文自家做的東西,它的native-image命令也可以把你的java應(yīng)用做成一個(gè)可執(zhí)行文件,而且也支持windows系統(tǒng)。
我寫(xiě)了個(gè)普通的HelloWorld:

我就用這個(gè)普通的類(lèi)來(lái)生成二進(jìn)制可執(zhí)行文件了!如下圖所示:

可以看到一個(gè)普通的hello world變成了一個(gè)可執(zhí)行的二進(jìn)制文件,唯一的缺點(diǎn)可能是文件有點(diǎn)大?但相比于直接把一個(gè)jre放在應(yīng)用中,要小很多了!
maven應(yīng)用可以使用native-image-maven-plugin這個(gè)plugin來(lái)自動(dòng)打包,我就不再寫(xiě)栗子了。
native-image也支持spring-boot的jar包,我就用剛剛的例子來(lái)試一下:

竟然報(bào)錯(cuò)了!其實(shí)spring-boot的jar跟普通的jar是有一點(diǎn)區(qū)別的233333,有興趣的小伙伴可以自己研究一下。spring-boot需要添加一些配置才能用graalvm的native-image,我簡(jiǎn)單折騰了一下,docker報(bào)了莫名其妙的錯(cuò)誤(攤手),唉,懶得繼續(xù)看了,總之spring-boot用native-image配置會(huì)比較麻煩,而且很可能會(huì)遇到一些兼容性問(wèn)題。
quakus和graalvm
quakus是近期火起來(lái)的一個(gè)框架,它跟graalvm集成的很好,可以直接通過(guò)其的maven插件生成可執(zhí)行文件:

java 16
java16引入了一個(gè)jpackage的命令,根據(jù)jep的描述它是源于javafx。我下載了java16來(lái)試一下,它需要一個(gè)jar文件,我把剛剛的HelloWorld打包成一個(gè)了jar,然后使用jpackage打包,如下所示:

可以看到所有的應(yīng)用文件都寫(xiě)入了一個(gè)文件里,也包括java運(yùn)行時(shí),可以使用jlink只引入必要的模塊。
接下來(lái)就是打包成deb或者rpm等安裝包了:

靠,怎么回事,我難道不是linux嗎?于是我看了看源碼:

我的系統(tǒng)是archlinux,既不是debain系也不是redhat系,所以找不到默認(rèn)的打包類(lèi)型,就算我指定deb或者rpm也不行,它依賴(lài)于dpkg-deb以及rpmbuild命令,所以我安裝了一下這倆工具,再次運(yùn)行:

成功生成deb安裝包了!文件大小好像也能夠接受的樣子
下面是規(guī)范的說(shuō)明,支持三種系統(tǒng)

jpackage還有很多很多的參數(shù),可以在oracle的文檔查看。?
參考鏈接:
https://www.graalvm.org/reference-manual/native-image/
https://www.graalvm.org/reference-manual/native-image/NativeImageMavenPlugin/
https://spring.io/blog/2020/11/23/spring-native-for-graalvm-0-8-3-available-now
https://openjdk.java.net/jeps/392
https://docs.oracle.com/javase/tutorial/deployment/jar/build.html
https://docs.oracle.com/en/java/javase/16/docs/specs/man/jpackage.html