maven打包fat-jar注意的问题
前言:maven打包fat-jar注意的问题,在使用maven工程的时候,打包jar的时候大多数都会需要把相关的jar依赖都一起打包到一起,这边记录下关于解压依赖和不解压依赖打包的两种方式以及嵌套jar包该如何解决的问题
maven配置
在使用maven打包jar包的时候,这边相关的配置都是在pom.xml中进行变动配置的。
这边需要用到maven-assembly-plugin,该插件的主要作用是把项目输出为一个单一可执行的jar文件,其中包含了所有的依赖项。
1、<mainClass>com.zpchcbd.TestMain</mainClass>
为指定应用程序启动时的主类。自己代码中的话,这边应用程序启动时的主类是com.zpchcbd.TestMain类
3、在<executions>
元素下,定义了一个执行阶段,其中<id>make-assembly</id>
,这是此次执行的唯一标识。<phase>package</phase>
指定在哪个Maven生命周期阶段运行该插件。在这里,它会在package阶段运行。<goal>single</goal>
,single目标意味着将所有部署文件和依赖项打包到一个单独的归档文件中。
预定义装配描述符
<plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.sdpost.Main</mainClass> </manifest> </archive> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
自定义装配描述符
<descriptor>src/assembly/package.xml</descriptor>
这个标签定义了一个打包描述符,它指明了如何创建集成包。在这里的话打包描述符文件路径是src/assembly/package.xml
,所以之后如何打包该jar的配置都是写在src/assembly/package.xml
路径中。
pom.xml
<build> <finalName>LandreyDecodePassword</finalName> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <!--可以不指定主类--> <mainClass>com.zpchcbd.TestMain</mainClass> </manifest> </archive> <descriptors> <!--这里的意思是依据指定的配置文件进行打包--> <descriptor>src/assembly/package.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
打包jar包(解压依赖)
在src/assembly/package.xml
中的配置就决定了该单一的jar包该如何进行打包,这边选择的是解压依赖,也就是会对其他相关的依赖jar包会解压然后再打包进单一的jar包中,其中起解压配置项的就是unpack
标签项,如果unpack为true的话就会把相关的依赖项都进行解压然后再进行打包进jar中。
package.xml
<assembly> <id>jar-with-dependencies</id> <formats> <format>jar</format> </formats> <includeBaseDirectory>false</includeBaseDirectory> <dependencySets> <dependencySet> <outputDirectory>/</outputDirectory> <useProjectArtifact>true</useProjectArtifact> <unpack>false</unpack> <scope>runtime</scope> </dependencySet> <dependencySet> <outputDirectory>/</outputDirectory> <unpack>false</unpack> <scope>system</scope> </dependencySet> </dependencySets> </assembly>
选择package操作之后就会生成一个LandreyDecodePassword-with-dependence.jar,该jar就是打包了所有依赖项的jar包,如下图所示
打开该jar包,解压依赖的体现可以看到该jar包无其他依赖的jar包存在,因为相关的class文件都是直接被解压进单一的jar包进行保存,如下图所示
打包jar包(非解压依赖)
同样的非解压依赖的话,这边只需要将unpack
标签项修改为false即可
package.xml
<assembly> <id>with-dependence</id><!-- 配置文件的标识,同时生成的jar包名字会把这个文本包含进去 --> <formats> <format>jar</format><!-- 打包类型,此处为jar --> </formats> <includeBaseDirectory>false</includeBaseDirectory> <dependencySets> <dependencySet> <unpack>false</unpack><!-- 是否解压 --> <scope>runtime</scope> </dependencySet> </dependencySets> <fileSets> <fileSet> <directory>${project.build.outputDirectory}</directory> <outputDirectory>/</outputDirectory> </fileSet> </fileSets> </assembly>
选择package操作之后再进行打开,可以看到该jar包里面直接包含了未解压的依赖jar包,如下图所示
嵌套jar包如何解决
遇到一个问题就是关于bouncycastle打包的问题,由于该包存在签名校验问题Caused by: java.util.jar.JarException: file:/C:/Users/user/IdeaProjects/LandreyDecodePassword/target/LandreyDecodePassword-with-dependence.jar has unsigned entries
,而解压依赖则会导致签名校验失败,如下图所示
但是如果使用非解压依赖的话单一jar又不支持嵌套jar包加载,所以这边的话我是通过SpringBoot来进行编写,SpringBoot有自定义加载器实现嵌套jar包加载,最终实现如下图所示
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>LandreyDecode</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>LandreyDecode Maven Webapp</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.15</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.50</version> </dependency> </dependencies> <build> <finalName>LandreyDecode</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <!--可以不指定主类--> <mainClass>com.zpchcbd.TestMain</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> </project>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南