当前位置: 首页 > news >正文

maven-plugin-shade 详解

一、介绍 [1]

This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies.

maven-plugin-shade 插件提供了两个能力

  1. 把整个项目(包含它的依赖)都打包到一个 "uber-jar" 中
  2. shade - 即重命名某些依赖的包

由此引出了两个问题

  1. 什么是 uber-jar ?

    uber-jar 也叫做 fat-jar 或者 jar-with-dependencies,意思就是包含依赖的 jar。

  2. 什么是 shade ?

    shade 意为遮挡,在此处可以理解为对依赖的 jar 包的重定向(主要通过重命名的方式)。

💁‍♂️ 下文中可能使用 shade 来代替 maven-plugin-shade。

二、基本使用 [2]

maven-plugin-shade 必须和 Maven 构建生命周期中的 package 阶段绑定,也就是说,当执行 mvn package 时会自动触发 shade。

要使用 maven-plugin-shade,只需要在 pom.xml 的 <plugins> 标签下添加它的配置即可,示例如下:

<project>...<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.2.4</version><configuration><!-- 此处按需编写更具体的配置 --></configuration><executions><execution><!-- 和 package 阶段绑定 --><phase>package</phase><goals><goal>shade</goal></goals></execution></executions></plugin></plugins></build>...
</project>

默认情况下会把项目所有的依赖都包含进最终的 jar 包中。当然,我们也可以在 <configuration> 标签内配置更具体的规则。

三、常用功能

3.1 按需选择要添加到最终 jar 包中依赖 [3]

使用 <includes> 排除不需要的依赖,示例如下:

<configuration><artifactSet><excludes><exclude>classworlds:classworlds</exclude><exclude>junit:junit</exclude><exclude>jmock:*</exclude><exclude>*:xml-apis</exclude><exclude>org.apache.maven:lib:tests</exclude><exclude>log4j:log4j:jar:</exclude></excludes></artifactSet>
</configuration>

使用 <filters> 结合 <includes> & <excludes> 标签可实现更灵活的依赖选择,示例如下:

<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>

除了可以通过自定义的 filters 来过滤依赖,此插件还支持自动移除项目中没有使用到的依赖,以此来最小化 jar 包的体积,只需要添加一项配置即可。示例如下:

<configuration><minimizeJar>true</minimizeJar>
</configuration>

3.2 重定位 class 文件 [4]

如果最终的 jar 包被其他的项目所依赖的话,直接地引用此 jar 包中的类可能会导致类加载冲突,这是因为 classpath 中可能存在重复的 class 文件。为了解决这个问题,我们可以使用 shade 提供的重定位功能,把部分类移动到一个全新的包中。示例如下:

<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>

涉及标签:

  • <pattern>:原始包名
  • <shadedPattern>:重命名后的包名
  • <excludes>:原始包内不需要重定位的类,类名支持通配符

例如,在上述示例中,我们把 org.codehaus.plexus.util 包内的所有子包及 class 文件(除了 ~.xml.Xpp3Dom 和 ~.xml.pull 包下的所有 class 文件)重定位到了 org.shaded.plexus.util 包内。

当然,如果包内的大部分类我们都不需要,一个个排除就显得很繁琐了。此时我们也可以使用 <includes> 标签来指定我们仅需要的类,示例如下:

<project>...<relocation><pattern>org.codehaus.plexus.util</pattern><shadedPattern>org.shaded.plexus.util</shadedPattern><includes><include>org.codehaud.plexus.util.io.*</include></includes></relocation>...
</project>

3.3 生成可执行 jar 包 [5]

使用 maven-plugin-shade 后,最终生成的 jar 包可以包含所有项目所需要的依赖。我们会想,能不能直接运行这个 uber-jar 呢?答案是当然可以,并且十分简单,只需要指定 <mainClass> 启动类就可以了。示例如下:

<project>...<configuration><transformers><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>org.sonatype.haven.HavenCli</mainClass></transformer></transformers></configuration>...
</project>

熟悉 jar 包的朋友们都知道,jar 包中默认会包含一个 MANIFEST.MF 文件,里面描述了一些 jar 包的信息。使用 java 自带的 jar 命令打包的时候可以指定 MANIFEST.MF,其中也可以指定 Main-Class 来使得 jar 包可运行。那么使用 shade 来指定和直接在 MANIFEST.MF 文件中指定有什么区别呢?

答案是没有区别,细心的读者会发现 <mainClass> 标签的父标签是 <transformer> 有一个 implementation 属性,其值为 "~.ManifestResourceTransformer",意思是 Manifest 资源文件转换器。上述示例只自指定了启动类,因此 shade 会为我们自动生成一个包含 Main-Class 的 MANIFEST.MF 文件,然后在打 jar 包时指定这个文件。

那如果我们想要完全定制 MANIFEST.MF 文件内容怎么办呢?我们可以使用 <manifestEntries> 标签,示例如下:

<project>...<configuration><transformers><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><manifestEntries><Main-Class>org.sonatype.haven.ExodusCli</Main-Class><Build-Number>123</Build-Number></manifestEntries></transformer></transformers></configuration>...
</project>

4.4 生成资源文件 [6]

项目中涉及到的依赖可能会有它们所必需的资源文件,使用 shade 可以把它们聚合在同一个 jar 包中。

默认地,shade 为我们提供了 12 个 ResourceTransformer 类:

类名作用
ApacheLicenseResourceTransformer防止 LICENSE 文件重复
ApacheNoticeResourceTransformer准备合并的 NOTICE
AppendingTransformer为某个资源文件附加内容
ComponentsXmlResourceTransformer聚合 Plexus components.xml
DontIncludeResourceTransformer防止包含指定的资源
GroovyResourceTransformer合并 Apache Groovy 的扩展模块
IncludeResourceTransformer添加项目中的文件为资源文件
ManifestResourceTransformer自定义 MANIFEST 文件
PluginXmlResourceTransformer聚合 Maven 的 plugin.xml 配置
ResourceBundleAppendingTransformer合并 ResourceBundles
ServicesResourceTransformer重定位且合并 META-INF/services 资源文件中的 class 文件.
XmlAppendingTransformer为 XML 资源文件附加内容

每种 ResourceTransformer 的具体使用可以点击对应链接查看官方示例,这里不再赘述。

如果上述 12 个类都不能够满足我们的需求,我们可以实现 shade 提供的接口,按需自定义一个 ResourceTransformer,实现方法详见官网 Using your own Shader implementation。

参考来源


  1. Apache Maven Shade Plugin – Introduction ↩︎

  2. Apache Maven Shade Plugin – Usage ↩︎

  3. http://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.htm ↩︎

  4. Apache Maven Shade Plugin – Relocating Classes ↩︎

  5. Apache Maven Shade Plugin – Executable JAR ↩︎

  6. Apache Maven Shade Plugin – Resource Transformers

相关文章:

maven-plugin-shade 详解

一、介绍 [1] This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies. maven-plugin-shade 插件提供了两个能力&#xff1a; 把整个项目&#xf…...

cocosCreator 之 3.x使用NodePool对象池和封装

版本&#xff1a; cocosCreator 3.4.0 语言&#xff1a; TypeScript 环境&#xff1a; Mac NodePool 在项目中频繁的使用instantiate和node.destory对性能有很大的耗费&#xff0c;比如飞机射击中的子弹使用和销毁。 因此官方提供了NodePool&#xff0c;它被作为管理节点对象…...

三、RestClient操作索引库与文档

文章目录 三、RestClient操作索引库与文档3.1 操作索引库3.2 操作文档结束语 三、RestClient操作索引库与文档 ES官方提供了各种不同语言的客户端&#xff0c;用来操作ES。这些客户端的本质就是组装DSL语句&#xff0c;通过http请求发送给ES。 官方文档地址: https://www.ela…...

Hadoop3教程(五):NameNode和SecondaryNameNode

文章目录 &#xff08;59&#xff09;NN和2NN的工作机制&#xff08;60&#xff09;FsImage镜像文件&#xff08;61&#xff09;Edits编辑日志&#xff08;62&#xff09;Checkpoint时间设置参考文献 &#xff08;59&#xff09;NN和2NN的工作机制 NameNode的数据是存储在磁盘…...

腾讯云我的世界mc服务器多少钱一年?

腾讯云我的世界mc服务器多少钱&#xff1f;95元一年2核2G3M轻量应用服务器、2核4G5M带宽优惠价218元一年、4核8G12M带宽轻量服务器446元一年&#xff0c;云服务器CVM标准型S5实例2核2G优惠价280元一年、2核4G配置服务器748元一年&#xff0c;腾讯云百科txybk.com分享腾讯云我的…...

modelsim实现二选一以及D触发器并仿真

#实验一 二选一 module two_1(in1,in2,cho,out); input[3:0] in1,in2; output[3:0] out; reg[3:0] out; input cho; always* begin if(cho0) outin1; else outin2; end endmodule module two1_test(); …...

直线导轨在喷涂行业中的应用场景

直线导轨因其具有精度高、速度快、刚性强、使用寿命长等特点被广泛应用在各行各种中&#xff0c;其中&#xff0c;在喷涂行业中的应用最为广泛&#xff0c;以下是直线导轨在喷涂行业中的应用场景&#xff1a; 1、平面喷涂&#xff1a;直线导轨可以应用在各种机械加工的平面&…...

纯css+js自制下拉框

前提 因为html的select标签&#xff0c;下拉框自定义程度非常的低&#xff0c;为了贴合而项目ui显示&#xff0c;所以打算自制下拉框 代码 html <div class"pos-rel"><div id"select" class"select get-select"><span class&…...

uniapp在App端如何动态修改原生导航栏?

uniapp在App端如何动态修改原生导航栏&#xff1f; 文章目录 uniapp在App端如何动态修改原生导航栏&#xff1f;page.json配置修改 buttons 文字修改按钮上的角标设置 searchInput的 focus设置 searchInput的 text 在App端可以通过得到 webview 对象&#xff0c;通过当前 webvi…...

Linux:CPUPower管理器 --- cpufreq解析

一、cpufreq是什么&#xff1f; cpufreq是Linux内核下的一种功率管理框架&#xff0c;它负责改变CPU的频率&#xff0c;以降低功耗并延长电池寿命。该框架的主要机制是动态调整CPU频率&#xff0c;该频率受限于CPU的负载和功耗。cpufreq能够动态地将频率降低到最低值或最高值&a…...

【嵌入式开发问答】不是普通的嵌入式八股

1. 进程、线程、堆栈、溢出 【问&#xff1a;】 进程的堆栈的物理内存是什么时候分配的&#xff1f; 堆栈的大小限制是多大&#xff1f;这个限制可以调整吗&#xff1f; 当堆栈发生溢出后应用程序会发生什么&#xff1f; 【答&#xff1a;】...

面试题-springboot篇-SpringBoot的注解

SpringBootApplication是SpringBoot的最核心的注解。 SpringBootApplication注解在SpringBoot的主类上&#xff0c;标识是SpringBoot应用&#xff0c;用来开启SpringBoot的各项能力。由SpringBootConfiguration、EnableAutoConfiguration、ComponentScan三个注解组成。这三个注…...

BaiChuan2保姆级微调范例

前方干货预警&#xff1a;这可能是你能够找到的&#xff0c;最容易理解&#xff0c;最容易跑通的&#xff0c;适用于各种开源LLM模型的&#xff0c;同时支持多轮和单轮对话数据集的大模型高效微调范例。 我们构造了一个修改大模型自我认知的3轮对话的玩具数据集&#xff0c;使用…...

postgresql参数优化

一 相关参数介绍 1.1 内存参数-shared_buffers shared_buffers&#xff1a;共享缓存区的大小&#xff0c;相当于oracle数据库中的SGA. 一般推荐为内存的四分之一&#xff0c;不超过总内存的二分之一。 该值默认是128M。 1.2 cpu并行参数-max_parallel_workers max_parall…...

【极速发表】2-4区SCI (含CCF),平均录用周期仅2个月,最快11天见刊!

一、计算机科学类SCI (11.30截稿) 【期刊概况】IF:4.0-5.0, JCR2区&#xff0c;中科院3区&#xff1b; 【检索情况】SCI在检&#xff0c;正刊&#xff1b; 【国人占比】10.58%&#xff1b; 【自引率】7.50%&#xff1b; 【年发文量】100篇以下&#xff1b; 【预警情况】无…...

Git 提交规范

遇到的问题 在项目中采用 git 管理代码版本时&#xff0c;突然不能进行提交&#xff08;git commit&#xff09;。 报错信息如下&#xff1a; ERROR invalid commit message format. Proper commit message format is required for automated changelog generation. Git 规范…...

[Python进阶] 操纵鼠标:PyAutoGUI

6.4 操纵鼠标&#xff1a;PyAutoGUI 6.4.1 说明 PyAutoGUI是一个Python的GUI自动化工具&#xff0c;它可以让程序自动控制鼠标和键盘的一系列操作。它能够模拟鼠标的移动、点击、拖拽等操作&#xff0c;以及键盘的按键按下和释放等操作。PyAutoGUI还提供了其他功能&#xff0…...

JavaScript querySelector

querySelector方法的语法&#xff1a; var element document.getElementById("id"); element.querySelector(selector)element是要执行选择操作的父元素&#xff0c;selector是CSS选择器&#xff0c;用于指定要选择的元素。 querySelector方法返回匹配选择器的第一…...

Selenium自动化测试

一、Selenium自动化测试&#xff08;基于python&#xff09; 1、Selenium简介&#xff1a; 1.1 Selenium是一款主要用于Web应用程序自动化测试的工具集合。Selenium测试直接运行在浏览器中&#xff0c;本质是通过驱动浏览器&#xff0c;模拟浏览器的操作&#xff0c;比如跳转…...

Lua调用C#类

先创建一个Main脚本作为主入口&#xff0c;挂载到摄像机上 public class Main : MonoBehaviour {// Start is called before the first frame updatevoid Start(){LuaMgr.GetInstance().Init();LuaMgr.GetInstance().DoLuaFile("Main");}// Update is called once p…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...

深入解析 ReentrantLock:原理、公平锁与非公平锁的较量

ReentrantLock 是 Java 中 java.util.concurrent.locks 包下的一个重要类,用于实现线程同步,支持可重入性,并且可以选择公平锁或非公平锁的实现方式。下面将详细介绍 ReentrantLock 的实现原理以及公平锁和非公平锁的区别。 ReentrantLock 实现原理 基本架构 ReentrantLo…...

20250609在荣品的PRO-RK3566开发板的Android13下解决串口可以执行命令但是脚本执行命令异常的问题

20250609在荣品的PRO-RK3566开发板的Android13下解决串口可以执行命令但是脚本执行命令异常的问题 2025/6/9 20:54 缘起&#xff0c;为了跨网段推流&#xff0c;千辛万苦配置好了网络参数。 但是命令iptables -t filter -F tetherctrl_FORWARD可以在调试串口/DEBUG口正确执行。…...