在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Java運行包精簡探索

jf_ro2CN3Fa ? 來源:jianshu ? 2023-01-31 16:42 ? 次閱讀

背景如下:

> 最近由于某些原因,需要做一個自帶運行環(huán)境的程序。由于各種原因,選定了 JavaPython 作為備選語言。但是 Java 由于 JRE 的臃腫(100M+)以及 Spring Boot 的日漸臃腫(helloworld 15M),需要在這兩方面進(jìn)行 size 的縮減。

基于 Spring Boot + MyBatis Plus + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

環(huán)境

系統(tǒng) :Ubuntu 16.04

GraalVM :GraalVM Community 21.3.0 (Based on OpenJDK 11.0.13)

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

環(huán)境準(zhǔn)備

關(guān)鍵配置

環(huán)境變量設(shè)置

exportJAVA_HOME=/path/to/
exportPATH=/path/to//bin:$PATH

安裝 native-image

guinstallnative-image

安裝 native-image 需要的組件

apt-getinstallbuild-essentiallibz-devzlib1g-dev

注意 :這里有個其他文章都沒有提到的坑。ld 需要更新到 2.26+,不然在構(gòu)建過程中會報告莫名其妙的異常(這里我耗了大半天)。

apt-getinstallbinutils-2.26

另一個坑

最開始我是在一臺 aliyun 的機器上實驗的,沒有注意到內(nèi)存問題,在實驗過程中遇到異常中斷。排查 syslog 發(fā)現(xiàn)是 OOMKiller。排查發(fā)現(xiàn)我的可用內(nèi)存只有 4G

后改為在本機機器 VMware 里的 Ubuntu 操作,內(nèi)存分配到 8G。經(jīng)觀察,native-image 打包過程中會用到 5.2G 左右的內(nèi)存,所以這里要注意一下。

至此,環(huán)境準(zhǔn)備完成。

打包

helloworld 的嘗試就跳過了,網(wǎng)上一搜一堆。先了解一下打包命令。

2fc54412-8bee-11ed-bfe3-dac502259ad0.png

項目依賴

3003537e-8bee-11ed-bfe3-dac502259ad0.png

主要用到了 solon、solon-api、h2、weed3、logback、slf4j、jlhttp 等包。

首先,通過 Maven 把我的項目 solondemo 打包為可以運行的 jar,確保通過。

java-jarsolondemo.jar

可以正常運行并訪問。然后把 solondemo.jar 上傳到前面準(zhǔn)備好的 GraalVM 環(huán)境。

首先,需要使用 GraalVM 提供的配置工具,對想要打包的程序的一些靜態(tài)分析無法分析到的信息進(jìn)行采集。

如果你確認(rèn)項目沒有使用任何反射、代理等特性,可以省略這一步。執(zhí)行

java-agentlib:native-image-agent=config-output-dir=./config/-jarsolondemo.jar

執(zhí)行后,最好能跑一跑 testcase,盡量保證代碼覆蓋率 100%,避免打包后遇到 classnotfound。

執(zhí)行完成后,終止執(zhí)行。

如果需要多次運行采集信息 可以使用如下命令再次執(zhí)行,工具會自動合并采集結(jié)果而不是覆蓋。

java-agentlib:native-image-agent=config-merge-dir=./config/-jarsolondemo.jar

執(zhí)行結(jié)束,config 下生成如下 5 個文件:

jni-config.json
predefined-classes-config.json
proxy-config.json
reflect-config.json
resource-config.json
serialization-config.json

坑又來了

根據(jù)網(wǎng)上的 說法,可以通過指定 -H:ConfigurationFileDirectories=./config 的方式來使用前面生成的配置文件。

但是,最后老是會把 -H:ConfigurationFileDirectories= 認(rèn)為是指定的生成文件名,然而根據(jù)文檔,-H:Name=xxx 才是指定輸出文件名的參數(shù)。

注意 :這個問題是開始在 CentOS 上操作遇到的,最后我在 Ubuntu 上又嘗試用這種方式指定配置文件的時候,它生效了,原因未知。

我采用了另外一種配置方式。把這些文件打包到 jar 包的 META-INF/native-image 目錄下。

3016a712-8bee-11ed-bfe3-dac502259ad0.png

打包命令:

native-image-jarsolondemo.jar--allow-incomplete-classpath-H:+ReportExceptionStackTraces--enable-http

這個命令也是經(jīng)過反復(fù)多次嘗試最終得出的可用命令,嘗試的過程就略去3W字了。

注意 :如果你的應(yīng)用需要對外提供 HTTP 服務(wù),必須加上配置 --enable-http。如果提供 HTTPS 服務(wù),則必須加 --enable-https。否則哪怕運行起來了訪問也永遠(yuǎn)是 500。打包成功,目錄下生成 solondem 文件。

執(zhí)行運行:運行成功了,但是插件沒加載。翻閱 solon 源碼,發(fā)現(xiàn)插件加載的流程大致如下:

30311aa2-8bee-11ed-bfe3-dac502259ad0.png

通過反復(fù)添加日志排查,發(fā)現(xiàn):

在 graalvm native-image 下運行,這里掃描到 META-INF/solon 這個目錄的 type,不是 file/jar,而是 resource。

304f28bc-8bee-11ed-bfe3-dac502259ad0.jpg

所以到了這里自然就無法遍歷目錄下的文件了。于是我嘗試讓 resource 類型也走 file 的方式去掃描。

3060731a-8bee-11ed-bfe3-dac502259ad0.png

調(diào)研搜索后發(fā)現(xiàn),GraalVM 內(nèi)部資源管理自己實現(xiàn)了一套 FileSystem,URL 描述符定義為 resource,有一套自定義的 API(由于時間有限,暫未深入研究)。

對本來是目錄類型的 resource 使用 File 方式去處理,得到的結(jié)果是 file not exists!但是對于確定的文件,是可以正常讀取的。

于是我考慮預(yù)處理,在 GraalVM 外面就先把能掃描到的文件清單提取出來,通過配置的方式,插件掃描的時候直接返回預(yù)置的文件清單。

因為本地執(zhí)行是可以正常掃描的,所以我在掃描結(jié)束的時候,增加一個輸出:

3077a008-8bee-11ed-bfe3-dac502259ad0.png

然后在配置中添加:

309a4e96-8bee-11ed-bfe3-dac502259ad0.jpg

scan 流程做如下修改

30a9125a-8bee-11ed-bfe3-dac502259ad0.png

插件掃描成功并運行。

30bdc75e-8bee-11ed-bfe3-dac502259ad0.png

掃描注解也有同樣的問題,排查過程與配置文件掃描類似,解決方案已與配置文件掃描的解決方案合并,略去 3萬字。

至此,主框架已經(jīng)可以 run 起來了,但是嵌入式數(shù)據(jù)庫 h2 還在作妖。

但是我嘗試按照他們說的 使用 1.4.199 版本,卻仍然各種異常。沒辦法,下載 h2 源碼 加 log 排查吧。

30e7278e-8bee-11ed-bfe3-dac502259ad0.png

首先,這里報空指針,那么唯一的可能就是 defaultProvider 為空。分析 defaultProvider 初始化過程:

310c32ae-8bee-11ed-bfe3-dac502259ad0.png

發(fā)現(xiàn)了 Class.forName,以及吃掉了異常:

e.printStackTrace();

打包,再來運行:

Causedby:java.lang.ClassNotFoundException
......
org.h2.store.fs.disk.FilePathDisk

好嘛。native-image 的 agent 居然沒有把這個掃出來。手動把這些添加到 reflect-config.json 里面,再打包運行。又報了個別的 class not found。再添加,再打包。

[
........,
{
"name":"org.h2.store.fs.FilePathDisk",
"methods":[{"name":"","parameterTypes":[]}]
},
{
"name":"org.h2.store.fs.FilePathMem",
"methods":[{"name":"","parameterTypes":[]}]
},
{
"name":"org.h2.store.fs.FilePathMemLZF",
"methods":[{"name":"","parameterTypes":[]}]
},
{
"name":"org.h2.store.fs.FilePathNioMem",
"methods":[{"name":"","parameterTypes":[]}]
},
{
"name":"org.h2.store.fs.FilePathNioMemLZF",
"methods":[{"name":"","parameterTypes":[]}]
},
{
"name":"org.h2.store.fs.FilePathNioMapped",
"methods":[{"name":"","parameterTypes":[]}]
},
{
"name":"org.h2.store.fs.FilePathAsync",
"methods":[{"name":"","parameterTypes":[]}]
},
{
"name":"org.h2.store.fs.FilePathZip",
"methods":[{"name":"","parameterTypes":[]}]
},
{
"name":"org.h2.store.fs.FilePathRetryOnInterrupt",
"methods":[{"name":"","parameterTypes":[]}]
},
{
"name":"org.h2.store.fs.FilePathNio",
"methods":[{"name":"","parameterTypes":[]}]
},
{
"name":"org.h2.store.fs.FilePathSplit",
"methods":[{"name":"","parameterTypes":[]}]
},
{
"name":"org.h2.mvstore.db.MVTableEngine",
"methods":[{"name":"","parameterTypes":[]}],
"allDeclaredFields":true
}
]

成了!

312d7414-8bee-11ed-bfe3-dac502259ad0.png

訪問接口、增刪改查、靜態(tài)頁面 、日志都 OK 了。

3179dd68-8bee-11ed-bfe3-dac502259ad0.png

幸福來得如此突然。

總結(jié)

最終可用的打包命令

native-image-jarsolondemo.jar--allow-incomplete-classpath-H:+ReportExceptionStackTraces--enable-http

ld 需要升級到 2.26+

root@ubuntu:/home/hx/graalvm/demo3#ld-version

GNUld(GNUBinutilsforUbuntu)2.26.1

Copyright(C)2015FreeSoftwareFoundation,Inc.
Thisprogramisfreesoftware;youmayredistributeitunderthetermsof
theGNUGeneralPublicLicenseversion3or(atyouroption)alaterversion.
Thisprogramhasabsolutelynowarranty.

其他注意事項

-agentlib:native-image-agent 不一定能檢查出所有的反射;

GraalVM 有自己的文件系統(tǒng)實現(xiàn),暫未找到遍歷目錄的方法;

第三方包不能運行時,大概率是由于反射沒有檢查到導(dǎo)致的 class not found;

排查第三方包問題時,一定要注意被吃掉的 Exception;

native-image 打包時需要 5G+ 內(nèi)存。

補充

1. native-image后序列化失敗問題(比如 JSON.toJSONString(JavaBean))

fastjson1.2.68 版本下在程序啟動時增加如下代碼:

ParserConfig.getGlobalInstance().setAsmEnable(false);
SerializeConfig.getGlobalInstance().setAsmEnable(false);

2. 反射方法報錯

需將反射類手動配置到 reflect-config.json 文件中,也可在編譯打包成 jar 時添加配置

-agentlib:native-image-agent=config-output-dir=../META-INF/native-image

后打包,然后 java -jar 或 java -cp 運行起來后,執(zhí)行對應(yīng)測試用例后,會自動將反射類信息生成到。

reflect-config.json 文件中(但真的不一定)。配置文件樣例:

[
{
"name":"com.test.A",
"allDeclaredFields":true,
"allPublicFields":true,
"queryAllPublicMethods":true,
"methods":[
{"name":"getA","parameterTypes":[]},
{"name":"getD","parameterTypes":[]},
{"name":"getF","parameterTypes":[]},
{"name":"getI","parameterTypes":[]},
{"name":"getQ","parameterTypes":[]},
{"name":"getR","parameterTypes":[]},
{"name":"getT","parameterTypes":[]},
{"name":"getY","parameterTypes":[]},
{"name":"getU","parameterTypes":[]},
{"name":"getV","parameterTypes":[]}
]
}
]

3. GraalVM 有自己的文件系統(tǒng)實現(xiàn)

暫未找到遍歷目錄的方法(即上文說說的).

如果你的程序中有涉及 ClassLoad.getResource("com.org") 這樣的代碼并打算對齊返回的結(jié)果以 File 或 jar 文件的方式掃描 com.org 下的所有類文件時會報錯。

解決方式如上文所說,手動配置需要掃描的類文件,然后讀取該配置(替代 getResource 方式)。

4. 控制 native 化后的二進(jìn)制程序內(nèi)存大小(配置參數(shù)不多說,一看就明白)

樣例:

./solondemo-Xmx16m-Xms16m-XX:MaxDirectMemorySize=8m






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • URL
    URL
    +關(guān)注

    關(guān)注

    0

    文章

    139

    瀏覽量

    15751
  • JAVA語言
    +關(guān)注

    關(guān)注

    0

    文章

    138

    瀏覽量

    20465
  • HTTP協(xié)議
    +關(guān)注

    關(guān)注

    0

    文章

    67

    瀏覽量

    10043
  • Ubuntu系統(tǒng)
    +關(guān)注

    關(guān)注

    0

    文章

    91

    瀏覽量

    4203
  • openjdk
    +關(guān)注

    關(guān)注

    0

    文章

    8

    瀏覽量

    2393

原文標(biāo)題:Java 運行包精簡探索(GraalVM)

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    java框架學(xué)習(xí)-Webwork2開發(fā)

    的wwexample中4:在WEB-INF中新建lib,把所有的jar包拷貝一份過去5:在Webwork-2.2.4發(fā)行包中找到taglib.tld,在/src/java/META-INF下面,拷貝到WEB-INF
    發(fā)表于 09-29 14:15

    [原創(chuàng)]java從代碼到運行的過程

    java從代碼到運行的過程 用一個圖來描述這個過程會比較容易理解:(鏈接地址:http://hiphotos.baidu.com/javass/pic/item
    發(fā)表于 10-31 11:44

    linux上的Java項目運行

    有一次我發(fā)現(xiàn),沒有服務(wù)器的root 和數(shù)據(jù)庫的root,用sqlplus查詢的亂碼問題實在是太難解決了,所以就采用了java的jdbc 的方法進(jìn)行查詢,但是我發(fā)現(xiàn)在linux上面運行java 項目帶 jar包的那種真的有點麻煩,
    發(fā)表于 07-24 06:58

    nodejs與java的互調(diào)用方法

    nodejs 與java的互調(diào)用方法很多,我們可選的是使用oracle 新的vm 引擎(graalvm很不錯) 還有就是基于browserify進(jìn)行包裝,同時給java 提供一套require
    發(fā)表于 11-04 07:31

    如何在嵌入式設(shè)備上運行高性能Java

    如何在嵌入式設(shè)備上運行高性能Java
    發(fā)表于 03-28 09:43 ?16次下載

    Java 運行環(huán)境的安裝、配置與運行

    Java 運行環(huán)境的安裝、配置與運行 一、實驗?zāi)康?    1. 掌握下載 Java SDK 軟件包。    2. 掌握設(shè)
    發(fā)表于 09-23 18:56 ?1.1w次閱讀

    java參考大全

    Java語言、庫及應(yīng)用程序進(jìn)行包括語法在內(nèi)的詳細(xì)介紹。我們將介紹Java語言產(chǎn)生的背景、發(fā)展過程,以及使它變得如此重要的原因。
    發(fā)表于 12-15 17:27 ?0次下載
    <b class='flag-5'>java</b>參考大全

    Java程序編譯和運行的過程

    Java 虛擬機(JVM)是可運行Java 代碼的假想計算機。只要根據(jù)JVM規(guī)格描述將解釋器移植到特定的計算機上,就能保證經(jīng)過編譯的任何Java代碼能夠在該系統(tǒng)上
    發(fā)表于 03-09 15:32 ?9231次閱讀

    Java程序是如何運行

    ? JVM是Java運行時虛擬機,所有的Java程序都是在JVM沙箱中運行,每個Java程序就是一個獨立的JVM進(jìn)程。 談到
    的頭像 發(fā)表于 12-27 09:31 ?1937次閱讀

    初學(xué)者:講解Java程序的開發(fā)與運行原理

    可能剛剛接觸編程的初學(xué)者會發(fā)現(xiàn),編寫一個Java程序其實很簡單,但是Java程序的運行過程卻是非常復(fù)雜的。關(guān)于Java程序工作原理這部分知識,雖然不要求編程學(xué)習(xí)者完全掌握,你但是至少需
    的頭像 發(fā)表于 08-13 15:01 ?3543次閱讀
    初學(xué)者:講解<b class='flag-5'>Java</b>程序的開發(fā)與<b class='flag-5'>運行</b>原理

    CA850 Ver.3.20 C編譯器運行包

    CA850 Ver.3.20 C編譯器運行包
    發(fā)表于 05-04 19:03 ?0次下載
    CA850 Ver.3.20 C編譯器<b class='flag-5'>運行包</b>

    eclipse怎么運行java項目

    在Eclipse中運行Java項目是非常簡單的。下面了解一下如何在Eclipse中運行Java項目。 首先,確保您已經(jīng)在Eclipse中創(chuàng)建了Jav
    的頭像 發(fā)表于 12-06 11:25 ?2347次閱讀

    eclipse設(shè)置java運行環(huán)境

    在Eclipse中設(shè)置Java運行環(huán)境是非常重要的,它能夠確保你的代碼能夠正確地編譯和運行。下面介紹如何設(shè)置Java運行環(huán)境。 下載和安裝J
    的頭像 發(fā)表于 12-06 11:29 ?1858次閱讀

    idea的java運行配置怎么弄

    Java是一種跨平臺的編程語言,可以通過Java虛擬機(JVM)在不同的操作系統(tǒng)和硬件上運行。在運行Java程序之前,需要進(jìn)行一些配置。本文
    的頭像 發(fā)表于 12-06 14:04 ?2313次閱讀

    java環(huán)境配置成功后怎么運行

    Java環(huán)境配置成功后,我們可以使用幾種方式來運行Java程序。下面將詳細(xì)介紹這幾種方式以及其使用方法。 命令行運行方式 在成功配置Java
    的頭像 發(fā)表于 12-06 15:57 ?2503次閱讀
    主站蜘蛛池模板: h小视频在线 | 深点再深一点好爽好多水 | 香港三级理论在线观看网站 | 免费一级在线 | 国产人免费人成免费视频 | 经典三级一区二区三区视频 | 国产精品久久久久久久牛牛 | 性色影院| 午夜爱爱网站 | 欧美在线资源 | 欧美在线观看www | 欧美日一区 | 刺激第一页720lu久久 | 国产亚洲第一伦理第一区 | 国产在线视频h | 免费一级大片 | 稀缺资源呦视频在线网站 | 狠狠色丁香久久综合网 | 久久99久久精品国产99热 | 国产在线h | 男人一级片 | 中文字幕第11页 | 在线观看一二三区 | 天天摸夜班摸天天碰 | 天天摸夜夜摸夜夜狠狠摸 | 日本一卡二卡≡卡四卡精品 | 黄色www网站| 亚洲影院手机版777点击进入影院 | 一色屋免费视频 | 成年美女黄网站色大免费视频 | www.九九热 | 亚欧美视频| aⅴ一区二区三区 | 婷婷综合五月天 | 色成人综合 | 米奇精品一区二区三区 | 色偷偷女男人的天堂亚洲网 | 天天做天天爰夜夜爽 | 亚洲无线码一区在线观看 | 国产伦精品一区二区 | 婷婷色在线播放 |