最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

用rust?寫一個jar包?class沖突檢測工具

 更新時間:2023年05月24日 08:24:52   作者:Aitozi  
這篇文章主要介紹了用rust?寫一個jar包?class沖突檢測工具?的相關(guān)資料,需要的朋友可以參考下

Rust很適合寫命令行工具,特別是使用clap crate 更加方便,這篇文章介紹使用rust寫一個jar包class沖突檢測的工具。項目地址: https://github.com/Aitozi/jar_conflict_detector

首先jar包class沖突的現(xiàn)象是多個jar包中有同名的class,并且class的md5還不一樣,那么就意味著該class存在多個版本,那么就存在沖突的可能。

思路比較簡單,就是遍歷每個jar包,記錄ClassName 和 對應(yīng) CRC 校驗碼 及 jar 包的對應(yīng)關(guān)系。

通過clap的derive api就可以快速定義個命令行的參數(shù)解析器。

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
#[arg(
short,
long = "jars",
required = true,
help = "The jar list joined by semicolon"
)]
jar_list: String,
#[arg(long, help = "Disable the crc check", action = clap::ArgAction::SetTrue)]
#[arg(default_value_t = false)]
disable_crc: bool,
#[arg(short, long, action = clap::ArgAction::Append, help = "The exclude package prefix")]
exclude: Vec<String>,
}

通過zip讀取jar包中的entry, 過濾只處理.class文件,并從zip_file中讀取crc32的元數(shù)據(jù),這樣可以避免讀取原始數(shù)據(jù)生成md5,可以大大加快處理速度。
中間編寫的時候遇到了一個常見的rust borrow checker的問題。

以下代碼為例

fn main() {
let path = "/tmp/a.jar";
let jar = File::open(path).unwrap();
let mut zip = ZipArchive::new(jar).unwrap();


for name in zip.file_names() {
let entry = zip.by_name(name);
println!("name: {}, size: {}", name, entry.unwrap().size());
}
}

我是想通過遍歷ZipArchive#file_names然后根據(jù)文件名獲取ZipFile但是會有如下編譯錯誤

pub fn file_names(&self) -> impl Iterator<Item = &str> {
self.shared.names_map.keys().map(|s| s.as_str())
}
/// Search for a file entry by name
pub fn by_name<'a>(&'a mut self, name: &str) -> ZipResult<ZipFile<'a>> {
Ok(self.by_name_with_optional_password(name, None)?.unwrap())
}

但是用以下的方式就沒有問題

let path = "/tmp/a.jar";
let jar = File::open(path).unwrap();
let mut zip = ZipArchive::new(jar).unwrap();

for i in 0..zip.len() {
let entry = zip.by_index(i).unwrap();
println!("name: {}, size: {}", entry.name(), entry.size());
}

這里我比較奇怪的是從方法簽名上看 len() 和 file_names()都會發(fā)生immutable borrow,而后面by_index 和 by_name都會發(fā)生mutable borrow。為什么會一個可以通過檢查,一個不行。

pub fn len(&self) -> usize {
self.shared.files.len()
}

len函數(shù)實際的簽名應(yīng)該是fn len<'a>(&'a self) -> usize 返回值是usize,所以函數(shù)調(diào)用完成后就不再和借用有關(guān)了。所以 immutable borrow 就結(jié)束了。
file_names實際簽名是fn file_names<'a>(&'a self) -> impl Iterator<Item = &'a str> {…}返回值的生命周期和 入?yún)⒌?immutable ref周期相同,所以后續(xù)就檢測出同時存在可變和不可變引用了。

詳細(xì)解釋: https://users.rust-lang.org/t/borrow-check-understanding/94260/2

命令行頻繁被Killed問題

問題現(xiàn)象是當(dāng)使用cargo build打包出binary后,通過cp 到 /tmp/jcd執(zhí)行 會出現(xiàn) Killed的情況,不是必現(xiàn),但是當(dāng)出現(xiàn)之后后續(xù)就一直會這樣,百思不得其解。

$ /tmp/jcd
[1] 16957 killed /tmp/jcd

后通過在rust user 論壇提問找到答案,不得不說回復(fù)效率很高。
https://users.rust-lang.org/t/rust-command-line-tools-keeps-beeing-killed/94179原因應(yīng)該是和蘋果電腦上的 Code sign機制有關(guān),在蘋果沒有解決這個問題之前,建議通過ditto替代cp命令來copy程序。

經(jīng)過檢查系統(tǒng)日志確實有出現(xiàn) Code Signature Invalid的報錯

相同的Class CRC和MD5卻不一樣

問題是發(fā)現(xiàn)在集成這個工具到內(nèi)部的插件框架中,集成過程中發(fā)現(xiàn)一個Jar包被另一個module依賴,經(jīng)過shade插件打包(沒有對相關(guān)class進(jìn)行relocate) 后,生成的class crc32不同,被識別為會沖突的類。通過javap -v 查看兩個class對比發(fā)現(xiàn)里面的僅僅是一些constant pool 不同。

那么懷疑就是maven-shade-plugin 做了什么操作,翻閱了下代碼,查看了shade的處理流程.

看到以下這段,發(fā)現(xiàn)這不就是我遇到的問題么。

查閱了相應(yīng)的issue: https://issues.apache.org/jira/browse/MSHADE-391在3.3.0 才解決,而我使用的版本正好是3.2.4。升級插件重新生成校驗碼一致了。

解決沖突的Class

最后再回到最初的目的,當(dāng)我們通過工具檢測出沖突的class應(yīng)該怎么解決呢。

首先我們需要判斷這個class是否是運行時所需要的。

如果不是所需要的那么我們就應(yīng)該直接排掉他,排除有兩種手段(這里針對的是maven shade的打包方式),如果在dependency tree中可以看到相應(yīng)package的依賴,那么可以直接通過如下的白名單 include 或者 exclude 掉某個 artifact。

<artifactSet combine.self="override">
<includes>
<include>commons-dbcp:commons-dbcp</include>
<include>commons-pool:commons-pool</include>
<include>mysql:mysql-connector-java</include>
</includes>
</artifactSet>

但是不排除這個依賴包本身就是fatjar,那么直接通過這種方式就排不掉這個依賴,可以通過filters 配置文件 粒度的匹配過濾

<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>javax/**</exclude>
<exclude>org/apache/flink/fnexecution/**</exclude>
<exclde>org/slf4j/**</exclde>
</excludes>
</filter>
</filters>

如果這個沖突的class是運行時需要的,那么可以通過relocation的方式給各自的插件包中shade成帶特殊前綴的class名,解決同名沖突。

<relocation>
<pattern>org.apache.http</pattern>
<shadedPattern>com.alipay.flink.sls.shaded.org.apache.http</shadedPattern>
</relocation>

到此這篇關(guān)于用rust 寫一個jar包 class沖突檢測工具 的文章就介紹到這了,更多相關(guān)rust 寫jar包 class沖突檢測工具 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 探索Rust切片與Go有何區(qū)別

    探索Rust切片與Go有何區(qū)別

    這篇文章主要為大家介紹了Rust切片與Go的區(qū)別探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • rust中trait的使用方法詳解

    rust中trait的使用方法詳解

    trait用中文來講就是特征,它就是一個標(biāo)記,只不過這個標(biāo)記被用在特定的地方,也就是類型參數(shù)的后面,下面我們就來學(xué)習(xí)一下trait的具體使用方法吧
    2023-12-12
  • Rust開發(fā)環(huán)境搭建到運行第一個程序HelloRust的圖文教程

    Rust開發(fā)環(huán)境搭建到運行第一個程序HelloRust的圖文教程

    本文主要介紹了Rust開發(fā)環(huán)境搭建到運行第一個程序HelloRust的圖文教程,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • Rust Atomics and Locks并發(fā)基礎(chǔ)理解

    Rust Atomics and Locks并發(fā)基礎(chǔ)理解

    這篇文章主要為大家介紹了Rust Atomics and Locks并發(fā)基礎(chǔ)理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Rust中箱、包和模塊的學(xué)習(xí)筆記

    Rust中箱、包和模塊的學(xué)習(xí)筆記

    Rust中有三個重要的組織概念:箱、包、模塊,本文主要介紹了Rust中箱、包和模塊的學(xué)習(xí)筆記,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • Rust cargo 命令行工具使用示例教程

    Rust cargo 命令行工具使用示例教程

    cargo 是 Rust 的構(gòu)建系統(tǒng)和包管理器,負(fù)責(zé)創(chuàng)建項目、編譯代碼、管理依賴、運行測試等,是日常開發(fā)中最常用的工具,這篇文章主要介紹了Rust cargo 命令行工具使用教程,需要的朋友可以參考下
    2025-04-04
  • rust智能指針的具體使用

    rust智能指針的具體使用

    智能指針是一些數(shù)據(jù)結(jié)構(gòu),它們的行為類似于指針但擁有額外的元數(shù)據(jù)和附加功能,本文就來介紹一下rust智能指針的具體使用,感興趣的可以了解一下
    2023-12-12
  • 深入剖析Rust 中的 Move、Copy 和 Clone

    深入剖析Rust 中的 Move、Copy 和 Clone

    在 Rust 編程語言中,move、Copy 和 Clone 是所有權(quán)系統(tǒng)的核心概念,它們深刻影響著數(shù)據(jù)的傳遞和復(fù)制方式,這些機制不僅確保了內(nèi)存安全,還提供了高效的性能優(yōu)化手段,本文將深入探討這些概念的內(nèi)部機制、使用場景、性能影響以及高級用法,感興趣的朋友一起看看吧
    2025-05-05
  • 從零開始使用Rust編寫nginx(TLS證書快過期了)

    從零開始使用Rust編寫nginx(TLS證書快過期了)

    wmproxy已用Rust實現(xiàn)http/https代理,?socks5代理,?反向代理,?負(fù)載均衡,?靜態(tài)文件服務(wù)器,websocket代理,四層TCP/UDP轉(zhuǎn)發(fā),內(nèi)網(wǎng)穿透等,本文給大家介紹從零開始使用Rust編寫nginx(TLS證書快過期了),感興趣的朋友一起看看吧
    2024-03-03
  • 詳解thiserror庫在Rust中的使用

    詳解thiserror庫在Rust中的使用

    在編程中,錯誤處理是一個至關(guān)重要的部分,在Rust中,我們經(jīng)常使用Result和Option類型來進(jìn)行錯誤處理,但有時,我們需要創(chuàng)建自定義的錯誤類型,這就是thiserror庫發(fā)揮作用的地方,可以極大的簡化代碼,所以本文就給大家介紹一下如何使用thiserror
    2023-08-08

最新評論

临武县| 靖宇县| 遂川县| 平遥县| 安福县| 五华县| 防城港市| 宣化县| 四平市| 海兴县| 读书| 霸州市| 洱源县| 正安县| 合肥市| 浦东新区| 库伦旗| 余庆县| 陵川县| 西峡县| 菏泽市| 嘉峪关市| 定边县| 青岛市| 隆林| 太和县| 洪雅县| 林西县| 阜宁县| 商城县| 新邵县| 宜城市| 石门县| 大新县| 咸丰县| 桑日县| 赤城县| 论坛| 阜宁县| 康平县| 微博|