Maven - 打包之爭:Jar vs. Shade vs. Assembly

文章目錄

  • Pre
  • 概述
  • Jar 打包方式_maven-jar-plugin
    • Overview
    • 使用
    • 官方文檔
  • Shade 打包方式_maven-shade-plugin
    • Overview
    • 使用
      • 將部分jar包添加或排除
      • 將依賴jar包內部資源添加或排除
      • 自動將所有不使用的類排除
      • 將依賴的類重命名并打包進來 (隔離方案)
      • 修改包的后綴名
    • 官方文檔
  • Assembly 打包方式_maven-assembly-plugin
    • Overview
    • 使用
    • 官方文檔

在這里插入圖片描述


Pre

Maven - 統一構建規范:Maven 插件管理最佳實踐

在這里插入圖片描述


概述

Maven 提供了多種打包方式,其中常見的包括三種:jar、shade、assembly。下面是它們的詳細比較:

  1. Jar 打包方式:

    • 描述: 這是最常見的打包方式,它創建一個標準的Java JAR文件。
    • 優點: 簡單直接,適用于大多數簡單項目。
    • 缺點: 不能包含項目的依賴,如果項目有外部依賴,用戶必須手動將它們添加到類路徑中。
  2. Shade 打包方式:

    • 描述: Maven Shade插件允許創建一個可執行的JAR文件,其中包含所有依賴。
    • 優點: 生成一個獨立的可執行JAR,無需用戶手動添加依賴。
    • 缺點: 可能會導致JAR文件較大,不適合所有項目。
  3. Assembly 打包方式:

    • 描述: Maven Assembly插件提供了一種更靈活的打包方式,允許創建各種自定義分發包。
    • 優點: 可以根據項目的需要創建定制的分發包,非常靈活。
    • 缺點: 配置相對復雜,適用于需要高度定制化的項目。

總結 :

  • Jar方式適用于簡單項目,但對于有依賴的項目需要手動處理依賴 ; 默認的打包方式,用來打普通的project JAR包;。
  • Shade方式生成可執行JAR,但可能導致文件較大; 用來打可執行jar包,也就是所謂的fat JAR包。
  • Assembly方式最靈活,可以根據項目需求創建定制分發包 ; 自定義的打包結構,也可以定制依賴項等。

Jar 打包方式_maven-jar-plugin

Overview

使用maven-jar-plugin插件, 默認的打包方式,用來打普通的project JAR包 .


使用

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.1.0</version><configuration><archive><manifest><!-- 指定入口函數 --><mainClass>類的全路徑名稱</mainClass><!-- 是否添加依賴的jar路徑配置 --><addClasspath>true</addClasspath><!-- 依賴的jar包存放位置,和生成的jar放在同一級目錄下 --><classpathPrefix>lib/</classpathPrefix></manifest></archive><!-- 不打包com.artisan.excludes下面的所有類 --><excludes>com/artisan/excludes/*</excludes></configuration></plugin></plugins>
</build>

上面配置使用這個 jar包的時候就需要在它同一級的創建一個lib目錄來存放。 可以使用includes或excludes選擇的打包某些內容

官方文檔

https://maven.apache.org/shared/maven-archiver/examples/classpath.html


Shade 打包方式_maven-shade-plugin

Overview

插件:使用maven-shade-plugin插件

maven-shade-plugin提供了兩大基本功能:

  • 將依賴的jar包打包到當前jar包(常規打包是不會將所依賴jar包打進來的);
  • 對依賴的jar包進行重命名(用于類的隔離);

使用

maven-shade-plugin 只存在一個goal shade:shade,需要將其綁定到 phase package 上

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.1.1</version><configuration><!-- put your configurations here --></configuration><executions><execution><phase>package</phase><goals><goal>shade</goal></goals></execution></executions></plugin></plugins>
</build>

然后在當前pom文件所在路徑下,執行打包命令:mvn clean package


將部分jar包添加或排除

<project>...<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.1.1</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><artifactSet><excludes><exclude>jmock:*</exclude><exclude>*:xml-apis</exclude><exclude>org.apache.maven:lib:tests</exclude><exclude>log4j:log4j:jar:</exclude></excludes><includes><include>junit:junit</include></includes></artifactSet></configuration></execution></executions></plugin></plugins></build>...
</project>
  • jar包以groupId:artifactId[[:type]:classifier]的形式表示
  • 1.3版本后插件支持通配符 ‘*’ and ‘?’

將依賴jar包內部資源添加或排除

<project>...<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.1.1</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><filters><filter><artifact>junit:junit</artifact><includes><include>junit/framework/**</include><include>org/junit/**</include></includes><excludes><exclude>org/junit/experimental/**</exclude><exclude>org/junit/runners/**</exclude></excludes></filter><filter><artifact>*:*</artifact><excludes><exclude>META-INF/*.SF</exclude><exclude>META-INF/*.DSA</exclude><exclude>META-INF/*.RSA</exclude></excludes></filter></filters></configuration></execution></executions></plugin></plugins></build>...
</project>

自動將所有不使用的類排除

<project>...<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.1.1</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><minimizeJar>true</minimizeJar></configuration></execution></executions></plugin></plugins></build>...
</project>

將依賴的類重命名并打包進來 (隔離方案)

<project>...<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.1.1</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><relocations><relocation><pattern>org.codehaus.plexus.util</pattern><shadedPattern>org.shaded.plexus.util</shadedPattern><excludes><exclude>org.codehaus.plexus.util.xml.Xpp3Dom</exclude><exclude>org.codehaus.plexus.util.xml.pull.*</exclude></excludes></relocation></relocations></configuration></execution></executions></plugin></plugins></build>...
</project>

將“org.codehaus.plexus.util”重命名為“org.shaded.plexus.util”,原始jar包中的“org.codehaus.plexus.util.xml.Xpp3Dom”和“org.codehaus.plexus.util.xml.pull”不會被重命名到目的包中;


修改包的后綴名

默認會生成一個Jar包和一個以 “-shaded”為結尾的uber-jar包,可以通過配置來指定uber-jar的后綴名。

<project>...<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.1.1</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><shadedArtifactAttached>true</shadedArtifactAttached><shadedClassifierName>jackofall</shadedClassifierName> <!-- Any name that makes sense --></configuration></execution></executions></plugin></plugins></build>...
</project>

Invalid signature file digest for Manifest main attributes

原因:有些jar包生成時,會 使用jarsigner生成文件簽名(完成性校驗),分為兩個文件存放在META-INF目錄下:

a signature file, with a .SF extension;
a signature block file, with a .DSA, .RSA, or .EC extension;

需要在生成 uber-jar時,將這些排除掉,不再進行完成性校驗,如下所示:

<configuration><filters><filter><artifact>*:*</artifact><excludes><exclude>META-INF/*.SF</exclude><exclude>META-INF/*.DSA</exclude><exclude>META-INF/*.RSA</exclude></excludes></filter></filters>
</configuration>

https://maven.apache.org/plugins/maven-shade-plugin/examples/attached-artifact.html


官方文檔

https://maven.apache.org/plugins/maven-shade-plugin/examples/attached-artifact.html


Assembly 打包方式_maven-assembly-plugin

Overview

使用maven-assembly-plugin插件 。

日常使用比較多的是maven-assembly-plugin插件

例如:大數據項目中往往有很多shell腳本、SQL腳本、.properties及.xml配置項等,采用assembly插件可以讓輸出的結構清晰而標準化


使用

首先在pom文件添加以下內容:

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>${maven-assembly-plugin.version}<version><executions><execution><id>make-assembly</id><!-- 綁定到package生命周期 --><phase>package</phase><goals><!-- 只運行一次 --><goal>single</goal></goals></execution></executions><configuration><!-- 配置描述符文件 --><descriptor>src/main/assembly/assembly.xml</descriptor><!-- 也可以使用Maven預配置的描述符<descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs> --></configuration></plugin></plugins>
</build>

然后編寫描述符文件:

<assembly><id>assembly</id><formats><format>tar.gz</format></formats><includeBaseDirectory>true</includeBaseDirectory><fileSets><fileSet><directory>src/main/bin</directory><includes><include>*.sh</include></includes><outputDirectory>bin</outputDirectory><fileMode>0755</fileMode></fileSet><fileSet><directory>src/main/conf</directory><outputDirectory>conf</outputDirectory></fileSet><fileSet><directory>src/main/sql</directory><includes><include>*.sql</include></includes><outputDirectory>sql</outputDirectory></fileSet><fileSet><directory>target/classes/</directory><includes><include>*.properties</include><include>*.xml</include><include>*.txt</include></includes><outputDirectory>conf</outputDirectory></fileSet></fileSets><files><file><source>target/${project.artifactId}-${project.version}.jar</source><outputDirectory>.</outputDirectory></file></files><dependencySets><dependencySet><unpack>false</unpack><scope>runtime</scope><outputDirectory>lib</outputDirectory></dependencySet></dependencySets>
</assembly>
字段解析
formats是assembly插件支持的打包文件格式,有zip、tar、tar.gz、tar.bz2、jar、war。可以同時定義多個formats。
id是添加到打包文件名的標識符,用來做后綴。比如說,如果按上面的配置,生成的文件就是artifactId-{artifactId}-artifactId-{version}-assembly.tar.gz
fileSets/fileSet用來設置一組文件在打包時的屬性。
directory源目錄的路徑。
includes/excludes設定包含或排除哪些文件,支持通配符。
fileMode指定該目錄下的文件屬性,采用Unix八進制描述法,默認值是064。
outputDirectory生成目錄的路徑。
files/file與fileSets大致相同,不過是指定單個文件,并且還可以通過destName屬性來設置與源文件不同的名稱。
dependencySets/dependencySet用來設置工程依賴文件在打包時的屬性,也與fileSets大致相同。
dependencySet-unpack布爾值,false表示將依賴以原來的JAR形式打包,true則表示將依賴解成*.class文件的目錄結構打包。
dependencySet-scope表示符合哪個作用范圍的依賴會被打包進去。compile與provided都不用管,一般是寫runtime。

按照以上配置打包好后,將.tar.gz文件上傳到服務器,解壓之后就會得到bin、conf、lib等規范化的目錄結構,十分方便。


官方文檔

https://maven.apache.org/plugins/maven-assembly-plugin/examples/single/filtering-some-distribution-files.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/168080.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/168080.shtml
英文地址,請注明出處:http://en.pswp.cn/news/168080.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ElasticSearch之cat component templates API

命令樣例如下&#xff1a; curl -X GET "https://localhost:9200/_cat/component_templates?vtrue&pretty" --cacert $ES_HOME/config/certs/http_ca.crt -u "elastic:ohCxPHQBEs5*lo7F9"執行結果輸出如下&#xff1a; name …

Qt/QML編程學習之心得:一個QML工程的學習筆記(十)

前言: 到底什么是Qt Quick呢?因為Qt Quick是Qt新引入的,Qt Quick由Qt Quick模塊提供,它是一個編寫QML應用的標準庫。Qt Quick模塊提供了兩種接口:使用QML語言創建應用的QML接口和使用C++語言擴展QML的C++接口。使用Qt Quick模塊,設計人員和開發人員可以輕松地構建流暢的…

【自主探索】基于 frontier_exploration 的單個機器人自主探索建圖

文章目錄 一、概述1、功能2、要求 二、使用方法1、用于運行演示2、用于開發人員2.1. 探索無/地圖數據2.2. 使用 /map 數據進行探索 三、提供的組件1、explore_client1.1. 調用的操作1.2. 訂閱主題1.3. 發布主題 2、explore_server2.1. 提供的操作2.2. 調用的操作2.3. 調用的服務…

【科技素養】藍橋杯STEMA 科技素養組模擬練習試卷6

1、將一個空塑料袋與一個裝滿空氣的塑料袋放到秤上稱重。在兩個塑料袋本身完全一樣的情況下&#xff0c;得出的結果會是 A、空塑料袋更重 B、裝滿空氣的塑料袋更重 C、兩個塑料袋一樣重 D、無法判斷 答案&#xff1a;C 2、全球變暖帶來的一個主要影響就是海平面的上升。造…

web前端開發基礎----標準流布局和非標準流布局

1&#xff0c;標準流布局 標準流&#xff0c;也稱文檔流或普通流&#xff0c;是所有元素默認的布局方式。 在標準流中&#xff0c;元素按照其在 HTML 中出現的順序&#xff0c;自上而下依次排列&#xff0c;并占據其父容器內的可用空間。 標準流中的元素按照其自然尺寸和位置進…

uniapp實現多時間段設置

功能說明&#xff1a; 1 點擊新增時間&#xff0c;出現一個默認時間段模板&#xff0c;不能提交 2 點擊“新增時間文本”&#xff0c;彈出彈窗&#xff0c;選擇時間&#xff0c;不允許開始時間和結束時間同時為00:00&#xff0c; <view class"item_cont"> …

TCP/IP協議:最流行的電子郵件協議SMTP(簡單郵件傳輸協議)詳解

SMTP 是一種電子郵件協議&#xff0c;用于通過互聯網從一個電子郵件帳戶向另一個電子郵件帳戶發送電子郵件。它是TCP/IP協議應用層的一部分。作為一種電子郵件協議&#xff0c;它建立了不同電子郵件客戶端和帳戶之間輕松信息交換的規則。這樣&#xff0c;簡單郵件傳輸協議就可以…

求最小的起始正整數

題目描述 給你一個整數數組 nums 。你可以選定任意的 正數 startValue 作為初始值。 你需要從左到右遍歷 nums 數組&#xff0c;并將 startValue 依次累加上 nums 數組中的值。 請你在確保累加和始終大于等于 1 的前提下&#xff0c;選出一個最小的 正數 作為 startValue 。…

【Rust 日報】2023-11-23 - egui 0.24 發布

項目 - egui 0.24 發布 egui 是一個易于使用的 Rust GUI 庫&#xff0c;支持在本地環境和瀏覽器中運行。 egui 0.24 的重要新特性是多視窗功能。在支持的后端上&#xff08;如eframe&#xff09;&#xff0c;用戶可以利用全新的 viewport API 同時生成多個本機窗口。 此外&…

Git 的基本概念和使用方式。

Git 是一個開源的分布式版本控制系統&#xff0c;它可以記錄代碼的修改歷史&#xff0c;跟蹤文件的版本變化&#xff0c;并支持多人協同開發。Git 的基本概念包括&#xff1a; 1. 倉庫&#xff08;Repository&#xff09;&#xff1a;存放代碼和版本歷史記錄的地方。 2. 分支…

ArkUI開發進階—@Builder函數@BuilderParam裝飾器的妙用與場景應用

ArkUI開發進階—@Builder函數@BuilderParam裝飾器的妙用與場景應用 HarmonyOS,作為一款全場景分布式操作系統,為了推動更廣泛的應用開發,采用了一種先進而靈活的編程語言——ArkTS。ArkTS是在TypeScript(TS)的基礎上發展而來,為HarmonyOS提供了豐富的應用開發工具,使開…

Educational Codeforces Round 158 (Rated for Div. 2)(A~E)(貪心,樹形DP)

A - Line Trip 題意&#xff1a;有一條路&#xff0c;可以用一條數線來表示。你位于數線上的點 0 &#xff0c;你想從點 0 到點 x &#xff0c;再回到點 0。你乘汽車旅行&#xff0c;每行駛 1個單位的距離要花費 1 升汽油。當您從點 0出發時&#xff0c;汽車已加滿油(油箱中的…

麒麟linux離線安裝dotnet core

1. 下載 dotnet core,以3.1為例 下載地址: 下載 .NET Core 3.1 (Linux、macOS 和 Windows) 查看linux cpu類型,然后根據類型下載 uname -m #結果是: aarch64 2. 放到指定目錄,比如:/usr/dotnet 3. 解壓dotnet-sdk-3.1.426-linux-arm64.tar.gz cd /usr/dotnet tar –zxvf a…

告別算法暗處:備案帶來的光明未來

在當今數字化時代&#xff0c;算法已經成為了企業發展和創新的關鍵推動力。然而&#xff0c;伴隨著算法的廣泛應用&#xff0c;數據隱私、知識產權和法規合規等問題也引發了越來越多的關切。為了解決這些問題&#xff0c;越來越多的公司開始意識到算法備案的重要性。本文將深入…

點云從入門到精通技術詳解100篇-基于深度學習的稀疏點云障礙物檢測(續)

目錄 3.1 連續幀點云空間特征融合 3.1.1 點云預處理 3.1.2 地面分割 3.1.3 自適應點云聚類

播放器開發(三):FFmpeg與SDL環境配置

學習課題&#xff1a;逐步構建開發播放器【QT5 FFmpeg6 SDL2】 環境配置 我這邊的是使用macOS&#xff1b;IDE用的是CLion&#xff1b;CMake構建&#xff0c;除了創建項目步驟、CMakeLists文件有區別之外的代碼層面不會有太大區別。 配置上只添加一下CMakeLists中FFmpeg和SD…

Ubuntu 22.04.3編譯AOSP13刷機

文章目錄 設備信息下載AOSP并切換分支獲取設備驅動編譯系統編譯遇到的問題Cannot allocate memoryUbuntu設置USB調試刷機參考鏈接 設備信息 手機&#xff1a;Pixel 4XL 下載AOSP并切換分支 在清華大學開源軟件鏡像站下載初始化包aosp-latest.tar。 解壓縮&#xff0c;切換到…

解決LocalDateTime傳輸前端為時間的數組

問題出現如下&#xff1a; 問題出現原因&#xff1a; 默認序列化情況下會使用SerializationFeature.WRITE_DATES_AS_TIMESTAMPS。使用這個解析時就會打印出數組。 解決方法&#xff1a; 我在全文搜索處理方法總結如下&#xff1a; 1.前端自定義函數來書寫 ,cols: [[ //表頭{…

[ubuntu]ubuntu上如何徹底卸載C++的opencv而不影響下次安裝使用

問題場景&#xff1a;我在ubuntu上安裝編譯了opencv3.4.4之后我又想安裝opencv4.5.0結果裝上后&#xff0c;opencv庫在系統目錄很混亂導致出現cmake項目出現很多錯誤。因此又想卸載掉opencv3.4.4重新安裝opencv4.5.0進去。但是如何卸載呢&#xff1f;我們知道opencv在系統里面有…

Go事件管理器:簡單實現

關注公眾號【愛發白日夢的后端】分享技術干貨、讀書筆記、開源項目、實戰經驗、高效開發工具等&#xff0c;您的關注將是我的更新動力&#xff01; 在編程中&#xff0c;事件管理器是一種常見的工具&#xff0c;用于通過通知來觸發操作。在Go語言中&#xff0c;我們可以通過創建…