如何在使用maven-dependency-plugin筛选依赖后创建含指定依赖的Jar包?
嘿,既然你已经用maven-dependency-plugin搞定了依赖的解压和筛选,接下来就差最后一步打包成包含指定依赖的Jar包了。这里有三种常用的方案,你可以根据自己的需求挑:
方案1:用maven-jar-plugin直接打包已解压的依赖
这种方式最直接,就是把你之前解压到target/dependency的依赖文件,和自己项目的代码、资源一起打包进同一个Jar里。如果是可执行Jar,别忘了指定主类:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <!-- 配置可执行Jar的主类,不需要可执行的话可以删掉这段 --> <archive> <manifest> <mainClass>com.yourpackage.YourMainClass</mainClass> </manifest> </archive> <!-- 包含所有必要的类文件和资源 --> <includes> <include>**/*.class</include> <include>**/*.properties</include> <include>**/*.xml</include> <!-- 按需添加你需要的其他资源类型 --> </includes> <!-- 把解压后的依赖目录加入资源范围,这样打包时会包含进去 --> <resources> <resource> <directory>target/dependency</directory> </resource> <resource> <directory>src/main/resources</directory> </resource> </resources> </configuration> </plugin>
配置完后,执行mvn clean package,target目录里的Jar就是包含所有筛选后依赖的包了。
方案2:用maven-assembly-plugin做灵活自定义打包
这个插件适合需要精确控制Jar结构的场景,它可以直接整合依赖筛选和打包步骤,也能复用你之前的dependency插件配置:
<!-- 先保留你之前的maven-dependency-plugin配置 --> <plugin> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <goals> <goal>unpack-dependencies</goal> </goals> <phase>prepare-package</phase> <configuration> <includeScope>runtime</includeScope> <excludes>META-INF/*.SF,META-INF/*.DSA,META-INF/*.RSA</excludes> <!-- 你的其他排除规则 --> </configuration> </execution> </executions> </plugin> <!-- 添加maven-assembly-plugin --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.6.0</version> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <!-- 用预定义的"jar-with-dependencies"描述符,一键打包所有依赖 --> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <!-- 配置可执行Jar的主类,不需要可执行就删掉 --> <archive> <manifest> <mainClass>com.yourpackage.YourMainClass</mainClass> </manifest> </archive> <!-- 可以进一步过滤内容,比如排除不需要的文件 --> <filters> <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>
执行mvn clean package后,target目录会生成一个带-jar-with-dependencies后缀的Jar包,里面就是整合了所有筛选依赖和你的代码的完整包。如果需要更自定义的结构(比如分目录存放依赖),可以写自己的assembly描述符文件(比如src/main/assembly/assembly.xml),然后在<descriptor>标签里指定路径。
方案3:用maven-shade-plugin解决依赖冲突
如果你的项目存在依赖版本冲突,或者需要合并META-INF下的配置文件(比如服务发现文件),shade插件是最佳选择——它可以重命名依赖的包路径,避免类冲突,同时也支持依赖筛选:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <!-- 配置可执行Jar主类,以及合并META-INF资源 --> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.yourpackage.YourMainClass</mainClass> </transformer> <!-- 合并META-INF/services下的文件,避免服务加载失败 --> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> </transformers> <!-- 复用你的依赖筛选规则 --> <filters> <filter> <artifact>*:*</artifact> <includeScope>runtime</includeScope> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> <!-- 你的其他排除规则 --> </excludes> </filter> </filters> <!-- 可选:重命名依赖包路径,彻底解决冲突 --> <relocations> <relocation> <pattern>com.example.conflicting.dependency</pattern> <shadedPattern>com.yourpackage.shaded.com.example.conflicting.dependency</shadedPattern> </relocation> </relocations> </configuration> </execution> </executions> </plugin>
执行mvn clean package后,target目录下的主Jar包就是包含所有筛选依赖的shaded包,原Jar会被备份为original-xxx.jar。这个方案特别适合复杂项目的依赖冲突问题。
小提示
- 简单打包选方案1或2就行;
- 有依赖冲突优先选方案3;
- 记得把配置里的
com.yourpackage.YourMainClass换成你自己的主类路径,排除规则也调整成你实际需要的。
内容的提问来源于stack exchange,提问作者Yaelz

