如何为Maven-assembly插件的每个执行打包仅对应程序使用的依赖
嘿,我来帮你把这个Maven多程序打包的配置给捋明白!你用maven-assembly-plugin+多执行节点的思路完全没问题,这正是实现多个独立Jar包(各带专属依赖)的标准玩法之一。下面给你一个完整的可复用配置示例,再唠唠关键细节:
完整的maven-assembly-plugin配置
直接把这段配置放到你的pom.xml的<build><plugins>节点里就行:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.6.0</version> <!-- 建议用最新稳定版 --> <executions> <!-- 打包Program1 --> <execution> <id>package-program1</id> <phase>package</phase> <!-- 绑定到package阶段执行 --> <goals> <goal>single</goal> <!-- 执行single目标生成打包文件 --> </goals> <configuration> <!-- 指定Jar包名称,会生成program1-with-deps.jar --> <finalName>program1-with-deps</finalName> <!-- 打包成包含所有依赖的Jar --> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <!-- 配置Manifest,指定Program1的主类 --> <archive> <manifest> <mainClass>com.yourpackage.Program1</mainClass> </manifest> </archive> <!-- 如果Program1有专属依赖,可以在这里过滤(可选) --> <dependencySets> <dependencySet> <includes> <include>com.specific:dependency-for-program1</include> </includes> </dependencySet> </dependencySets> </configuration> </execution> <!-- 打包Program2 --> <execution> <id>package-program2</id> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <finalName>program2-with-deps</finalName> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.yourpackage.Program2</mainClass> </manifest> </archive> <!-- 同理,这里可以配置Program2的专属依赖过滤 --> </configuration> </execution> <!-- 打包Program3,照着上面的格式复制修改就行 --> <execution> <id>package-program3</id> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <finalName>program3-with-deps</finalName> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.yourpackage.Program3</mainClass> </manifest> </archive> </configuration> </execution> </executions> </plugin>
关键细节提示
- 每个execution的id必须唯一:比如上面的
package-program1、package-program2,Maven靠这个区分不同的执行任务。 - 主类配置别写错:
<mainClass>里要填你每个Java程序的完整类名(包名+类名),不然Jar包没法直接运行。 - 专属依赖过滤:如果某个程序只需要部分依赖,就用
<dependencySets>里的<includes>/<excludes>来筛选,避免打包冗余依赖。 - 版本号要指定:记得给
maven-assembly-plugin加上稳定版本号,避免Maven自动拉取旧版本出问题。
可选替代方案:maven-shade-plugin
如果你遇到依赖冲突(比如多个程序依赖不同版本的同一个库),可以试试maven-shade-plugin,它支持对依赖包重命名,解决冲突问题。给你一个简单的多执行节点示例:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.5.1</version> <executions> <execution> <id>shade-program1</id> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <finalName>program1-shaded</finalName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.yourpackage.Program1</mainClass> </transformer> </transformers> <!-- 可选:重命名冲突的依赖包 --> <relocations> <relocation> <pattern>org.apache.commons.lang</pattern> <shadedPattern>com.yourpackage.shaded.commons.lang</shadedPattern> </relocation> </relocations> </configuration> </execution> <!-- Program2、Program3的配置照着复制修改即可 --> </executions> </plugin>
两种插件各有优势:assembly更灵活,适合简单的打包需求;shade在处理依赖冲突、自定义包重命名上更强大,你可以根据自己的项目情况选。
内容的提问来源于stack exchange,提问作者revy




