Maven 打包排除特定依賴的完整指南(詳細方法 + 示例)

前言

在使用 Maven 構建 Java 項目時,我們常常需要對項目的打包過程進行精細化控制,尤其是希望排除某些特定的依賴庫。這可能是為了減小最終構建產物的體積、避免版本沖突,或者僅僅是為了滿足不同環境下的部署需求。

本文將詳細介紹如何在 Maven 打包過程中排除特定依賴,涵蓋多種常見插件和配置方式,幫助你靈活控制項目的打包內容。


一、理解 Maven 的依賴作用域(Scope)

在深入討論排除依賴之前,先了解 Maven 中的依賴作用域是非常重要的。不同的作用域決定了依賴是否會被包含在構建輸出中:

Scope描述
compile默認作用域,適用于所有階段(編譯、測試、運行)
provided編譯和測試階段可用,但不會被打包進最終輸出(如 Servlet API)
runtime運行和測試階段需要,但編譯不需要(如 JDBC 驅動)
test僅用于測試階段,不會被打包
system類似于 provided,但必須顯式指定本地路徑
import僅用于 <dependencyManagement> 中導入其他 POM 的依賴

最佳實踐建議:優先使用合適的 scope 來控制依賴是否被打包,而不是通過插件強行剔除。


二、使用 Maven Shade Plugin 排除依賴

如果你使用的是 maven-shade-plugin 來構建一個包含所有依賴的 fat jar(即 uber jar),可以通過 <excludes> 標簽來排除特定依賴。

示例配置:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.5.0</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><excludes><exclude>com.example:unwanted-library</exclude><exclude>org.slf4j:slf4j-simple</exclude></excludes><transformers><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>com.example.Main</mainClass></transformer></transformers></configuration></execution></executions>
</plugin>

說明

  • <exclude> 的格式為 groupId:artifactId,可以精確到版本號。
  • 適合用于構建包含多個模塊和依賴的單體 JAR 包。

三、使用 Maven Assembly Plugin 排除依賴

如果你使用 maven-assembly-plugin 來打包一個包含依賴的 zip/jar 包,也可以通過 <excludes> 來排除某些依賴。

示例配置:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>3.6.0</version><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifest><mainClass>com.example.Main</mainClass></manifest></archive><excludes><exclude>com.example:unwanted-library</exclude><exclude>org.slf4j:slf4j-api</exclude></excludes></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions>
</plugin>

提示:Assembly 插件還支持自定義 assembly.xml 文件,實現更細粒度的控制。


四、使用 Maven Jar Plugin 排除資源或類文件

默認的 maven-jar-plugin 不會把依賴打進 JAR 包中,但如果你有特殊需求(如手動管理 lib 目錄),可以用來排除某些資源或類文件。

示例配置(排除資源):

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.7.0</version><configuration><excludes><exclude>**/unwanted/**</exclude></excludes></configuration>
</plugin>

五、使用 Maven Dependency Plugin 清理依賴

如果你想在打包前主動清理某些依賴,可以使用 maven-dependency-plugin 來復制依賴并排除部分庫。

示例配置:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><version>3.6.0</version><executions><execution><id>copy-dependencies</id><phase>package</phase><goals><goal>copy-dependencies</goal></goals><configuration><outputDirectory>${project.build.directory}/lib</outputDirectory><overWriteReleases>false</overWriteReleases><overWriteSnapshots>false</overWriteSnapshots><overWriteIfNewer>true</overWriteIfNewer><excludes><exclude>com.example:unwanted-library</exclude></excludes></configuration></execution></executions>
</plugin>

此方法適合手動構建 lib 目錄,并配合 shell 腳本或 Dockerfile 使用。


六、Docker 構建中排除依賴(Maven + Docker)

如果你使用 Maven 構建鏡像(如結合 Jib、Dockerfile 等),可以在構建應用 JAR 包時就排除依賴,再將其 COPY 到 Docker 鏡像中。

示例(結合 jib-maven-plugin):

<plugin><groupId>com.google.cloud.tools</groupId><artifactId>jib-maven-plugin</artifactId><version>3.3.2</version><configuration><container><entrypoint><arg>java</arg><arg>-cp</arg><arg>/app/resources:/app/classes:/app/libs/*</arg><arg>com.example.Main</arg></entrypoint></container><extraDirectories><paths><path><from>src/main/resources</from><into>/app/resources</into></path></paths></extraDirectories></configuration>
</plugin>

在此示例中,你可以先通過其他方式控制哪些依賴被放入 /app/libs/


七、使用 <scope> 顯式排除依賴

最簡單且推薦的方式是直接在 pom.xml 中設置依賴的作用域為 testprovided,這樣它們就不會被打包進最終輸出。

示例:

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope>
</dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope>
</dependency>

Maven 會根據作用域自動決定是否將該依賴包含在構建輸出中。


八、使用 <optional> 標記依賴為可選

如果你開發的是一個庫(library),并且某個依賴不是必需的,可以將其標記為 <optional>true</optional>,這樣引入你的庫的項目可以選擇是否包含這個依賴。

示例:

<dependency><groupId>com.example</groupId><artifactId>some-utils</artifactId><version>1.0.0</version><optional>true</optional>
</dependency>

注意:<optional> 不會影響當前項目的打包行為,而是影響下游項目的依賴管理。


九、使用 <exclusion> 排除傳遞性依賴

有時你想排除某個依賴的子依賴(transitive dependency),可以使用 <exclusions>

示例:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion><exclusion><groupId>org.slf4j</groupId><artifactId>log4j-over-slf4j</artifactId></exclusion></exclusions>
</dependency>

這種方式非常適合解決依賴沖突或精簡依賴樹。


十、綜合建議與最佳實踐

場景推薦做法
測試依賴不打包設置 <scope>test</scope>
容器已提供依賴(如 Tomcat、JDK)設置 <scope>provided</scope>
某些依賴不想被打入最終 JAR/WAR使用 Shade / Assembly 插件配置 <excludes>
排除某個依賴的子依賴使用 <exclusions> 標簽
控制依賴是否傳遞給下游項目使用 <optional>true</optional>
構建 lib 目錄時排除某些庫使用 maven-dependency-plugin<excludes>
構建 Docker 鏡像時排除依賴結合上述方法先處理好 JAR 再 COPY

總結

Maven 提供了多種靈活的方式來排除特定依賴,從簡單的 <scope> 到復雜的插件配置,開發者可以根據實際需求選擇最合適的方法。合理使用這些技巧不僅可以減小最終包的體積,還能有效避免依賴沖突問題,提高構建效率和部署穩定性。


常見問答

Q:我只想排除某個依賴的一個 jar 文件?

A:可以使用 <exclusion> 排除其子依賴,或者使用插件配置 <excludes>

Q:為什么設置了 <scope>provided</scope> 依賴仍然被打包?

A:檢查是否被其他插件強制引入,例如 maven-shade-plugin

Q:我想在 Spring Boot 項目中排除某些 starter 自帶的依賴怎么辦?

A:使用 <exclusions> 標簽,在對應的 starter 依賴中聲明要排除的子依賴。

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

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

相關文章

Terraform `for_each` 精講:優雅地自動化多域名證書驗證

大家好&#xff0c;在云原生和自動化運維的世界里&#xff0c;Terraform無疑是基礎設施即代碼&#xff08;IaC&#xff09;領域的王者。它強大的聲明式語法讓我們能夠輕松地描述和管理云資源。然而&#xff0c;即使是經驗豐富的工程師&#xff0c;在面對某些動態場景時也可能會…

C++標準庫中各種互斥鎖的用法 mutex

示例 僅供參考學習 #include <mutex> #include <shared_mutex> #include <thread> #include <chrono> #include <iostream> #include <vector>// // 1. std::mutex - 基本互斥鎖 // void basic_mutex_example() {std::mutex mtx;int cou…

Android Handler機制與底層原理詳解

Android 的 Handler 機制是跨線程通信和異步消息處理的核心框架&#xff0c;它構成了 Android 應用響應性和事件驅動模型的基礎&#xff08;如 UI 更新、后臺任務協調&#xff09;。其核心思想是 “消息隊列 循環處理”。 核心組件及其關系Handler (處理器): 角色: 消息的發送…

jQuery JSONP:實現跨域數據交互的利器

jQuery JSONP&#xff1a;實現跨域數據交互的利器 引言 隨著互聯網的發展&#xff0c;跨域數據交互的需求日益增加。在Web開發中&#xff0c;由于同源策略的限制&#xff0c;直接通過XMLHttpRequest請求跨域數據會遇到諸多問題。而JSONP&#xff08;JSON with Padding&#xff…

Redis集群和 zookeeper 實現分布式鎖的優勢和劣勢

在分布式系統中&#xff0c;實現分布式鎖是確保多個節點間互斥訪問共享資源的一種常見需求。Redis 集群 和 zookeeper 都可以用來實現這一功能&#xff0c;但它們有著各自不同的優勢和劣勢。 CAP 理論&#xff1a; 在設計一個分布式系統時&#xff0c;一致性&#xff08;Consis…

如何備份vivo手機中的聯系人?

隨著vivo移動設備在全球設立7個研發中心&#xff0c;vivo正在進入更多的國家。如今&#xff0c;越來越多的人開始使用vivo手機。以vivo X100為例&#xff0c;它配備了主攝像頭和多個輔助攝像頭&#xff0c;提供多樣化的拍攝選項&#xff0c;并搭載了最新的FunTouch OS&#xff…

python腳本編程:使用BeautifulSoup爬蟲庫獲取熱門單機游戲排行榜

BeautifulSoup是一個便捷的解析html頁面元素的python庫&#xff0c;此處用來寫一個簡單的爬蟲批量抓取國內游戲資訊網站的近期熱門單機游戲排行榜。 網頁來源如下所示代碼 from bs4 import BeautifulSoup import requests# get web page web_url "https://www.3dmgame.co…

C#配置全面詳解:從傳統方式到現代配置系統

C#配置全面詳解&#xff1a;從傳統方式到現代配置系統 在軟件開發中&#xff0c;配置是指應用程序運行時可調整的參數集合&#xff0c;如數據庫連接字符串、API 地址、日志級別等。將這些參數從代碼中分離出來&#xff0c;便于在不修改代碼的情況下調整應用行為。C# 提供了多種…

數據中臺架構解析:湖倉一體的實戰設計

目錄 一、數據中臺與湖倉一體架構是什么 1. 數據中臺 2. 湖倉一體架構 3. 湖倉一體在數據中臺里的價值 二、湖倉一體架構的核心部件 1. 數據湖 2. 數據倉庫 3. 數據集成工具 4. 數據分析與處理引擎 三、湖倉一體架構實戰設計 1. 需求分析與規劃 2. 數據湖建設 3. …

SQL Server表分區技術詳解

表分區概述 表分區是將大型數據庫表物理分割為多個較小單元的技術,邏輯上仍表現為單一實體。該技術通過水平分割數據顯著提升查詢性能,尤其針對TB級數據表可降低90%的響應時間。典型應用場景包含訂單歷史表、日志記錄表等具有明顯時間特征的業務數據,以及需要定期歸檔的審計…

WHIP(WebRTC HTTP Ingestion Protocol)詳解

WHIP&#xff08;WebRTC HTTP Ingestion Protocol&#xff09;詳解 WHIP&#xff08;WebRTC HTTP Ingestion Protocol&#xff09;是一種基于 HTTP 的協議&#xff0c;用于將 WebRTC 媒體流推送到媒體服務器&#xff08;如 SRS、Janus、LiveKit&#xff09;。它是為簡化 WebRT…

圖像噪點消除:用 OpenCV 實現多種濾波方法

在圖像處理中&#xff0c;噪點是一個常見的問題。它可能是由于圖像采集設備的缺陷、傳輸過程中的干擾&#xff0c;或者是光照條件不佳引起的。噪點會影響圖像的質量和后續處理的效果&#xff0c;因此消除噪點是圖像預處理的重要步驟之一。本文將介紹如何使用 OpenCV 實現幾種常…

AI的Prompt提示詞:英文寫好還是中文好?

在與AI人大模型交互時,Prompt(提示詞)的質量直接決定了輸出的精準度和有效性。一個常見的問題是:究竟是用英文寫Prompt好,還是用中文寫更好?這并非一個簡單的二元選擇,而是涉及到語言模型的底層邏輯、表達的精確性以及個人使用習慣的綜合考量。 英文Prompt的優勢 模型訓…

react的條件渲染【簡約風5min】

const flag1true; console.log(flag1&&hello); console.log(flag1||hello); const flag20; console.log(flag2&&hello); console.log(flag2||hello); // &&運算符&#xff0c;如果第一個條件為假&#xff0c;則返回第一個條件&#xff0c;否則返回第二…

【RK3568+PG2L50H開發板實驗例程】FPGA部分 | 紫光同創 IP core 的使用及添加

本原創文章由深圳市小眼睛科技有限公司創作&#xff0c;版權歸本公司所有&#xff0c;如需轉載&#xff0c;需授權并注明出處&#xff08;www.meyesemi.com)1.實驗簡介實驗目的&#xff1a;了解 PDS 軟件如何安裝 IP、使用 IP 以及查看 IP 手冊實驗環境&#xff1a;Window11 PD…

thinkphp微信小程序一鍵獲取手機號登陸(解密數據)

微信小程序獲取手機號登錄的步驟相對較為簡單,主要分為幾個部分: 1.用戶授權獲取手機號: 微信小程序通過調用 wx.getPhoneNumber API 獲取用戶授權后,獲取手機號。 2.前端獲取用戶的手機號: 用戶在小程序中點擊獲取手機號時,系統會彈出授權框,用戶同意后,你可以通過 …

數據庫設計精要:完整性和范式理論

文章目錄數據的完整性實體的完整性主鍵域完整性參照完整性外鍵多表設計/多表理論一對一和一對多多對多數據庫的設計范式第一范式&#xff1a;原子性第二范式&#xff1a;唯一性第三范式&#xff1a;不冗余性數據的完整性 實體的完整性 加主鍵&#xff0c;保證一個表中每一條數…

智能推薦社交分享小程序(websocket即時通訊、協同過濾算法、時間衰減因子模型、熱度得分算法)

&#x1f388;系統亮點&#xff1a;websocket即時通訊、協同過濾算法、時間衰減因子模型、熱度得分算法&#xff1b;一.系統開發工具與環境搭建1.系統設計開發工具后端使用Java編程語言的Spring boot框架項目架構&#xff1a;B/S架構運行環境&#xff1a;win10/win11、jdk17小程…

部署NextCloud AIO + Frp + nginx-proxy-manager內網穿透私有云服務

網絡拓撲 假設已有域名為nextcloud.yourhost.com 用戶通過域名https訪問 -> Nginx -> frps -> frpc -> NextCloud 其中Nginx和frps安裝在具有公網IP的服務器上&#xff0c;frpc和NextCloud安裝在內網服務器中。 Nginx配置 通過docker安裝nginx-proxy-manager 外…

【源力覺醒 創作者計劃】文心開源大模型ERNIE-4.5-0.3B-Paddle私有化部署保姆級教程及技術架構探索

一起來輕松玩轉文心大模型吧&#x1f449;一文心大模型免費下載地址: https://ai.gitcode.com/theme/1939325484087291906 前言 2025年6月30日&#xff0c;百度正式開源文心大模型4.5系列&#xff08;ERNIE 4.5&#xff09;&#xff0c;涵蓋10款不同參數規模的模型&#xff0…