
本文详解为何 maven-shade-plugin 未生效的常见原因——误将插件声明置于 中,并提供完整、可落地的配置方案,确保 mvn package 正确触发 Shade 插件构建包含依赖的可运行 JAR。
本文详解为何 `maven-shade-plugin` 未生效的常见原因——误将插件声明置于 `
在多模块 Maven 项目中,若希望为特定子模块(如 simple-client 或 simple-server)生成包含所有运行时依赖的「Fat Jar」(即 Uber JAR),maven-shade-plugin 是最常用且可靠的工具。但实践中常出现「执行 mvn package 后却只生成普通 JAR(由 maven-jar-plugin 生成),Shade 插件完全未执行」的问题——这并非插件版本或生命周期冲突所致,而是一个典型的配置作用域误解。
? 根本原因: ≠
Maven 中:
仅用于集中声明插件的默认配置和版本,它本身不会绑定插件到生命周期,也不会触发执行; (即顶层 plugins 块)才真正将插件声明“激活”,使其在对应 phase(如 package)中运行。
在你的 simple-client/pom.xml 中,Shade 插件被错误地放在
<build><pluginmanagement><plugins><plugin><groupid>org.apache.maven.plugins</groupid><artifactid>maven-shade-plugin</artifactid><!-- ... --></plugin></plugins></pluginmanagement></build>
✅ 正确做法是:移出
<build><finalname>Server</finalname><plugins><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><transformers><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainclass>com.firstproject.myapp.AppServer</mainclass></transformer></transformers><minimizejar>false</minimizejar><createdependencyreducedpom>false</createdependencyreducedpom><dependencyreducedpomlocation>${java.io.tmpdir}/dependency-reduced-pom.xml</dependencyreducedpomlocation><relocations><relocation><pattern>com.firstproject.myapp</pattern><shadedpattern>hidden.coyote</shadedpattern></relocation></relocations></configuration></execution></executions></plugin></plugins></build>
? 提示:
仍保留在 根层级下,它影响最终 JAR 文件名(如生成 Server.jar 而非默认的 simple-client-1.0-SNAPSHOT.jar)。
✅ 验证与最佳实践
验证是否生效:执行 mvn clean package -X(开启 debug 日志),搜索 maven-shade-plugin:3.4.1:shade,确认其出现在 package phase 日志中;同时检查 target/ 目录下是否生成了 Server.jar(而非 Server-1.0-SNAPSHOT.jar)及 Server-original.jar(原始 jar)。
避免父 POM 干预:你当前的 parent-project 使用 packaging=pom 且
为空,这是推荐做法——父 POM 不应定义具体插件行为,子模块按需独立声明。若未来需统一 Shade 配置(如所有可执行模块共用相同 mainClass 模式),可在父 POM 的 中预设,但每个子模块仍必须在自身 中显式引用该插件 :
<!-- 父 POM 中(仅管理) --> <pluginmanagement><plugins><plugin><groupid>org.apache.maven.plugins</groupid><artifactid>maven-shade-plugin</artifactid><version>3.4.1</version><configuration><createdependencyreducedpom>false</createdependencyreducedpom></configuration></plugin></plugins></pluginmanagement>
<!-- 子模块中(必须显式启用) --> <build><plugins><plugin><groupid>org.apache.maven.plugins</groupid><artifactid>maven-shade-plugin</artifactid><!-- 版本继承自 pluginManagement,无需重复声明 --><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><transformers><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainclass>com.firstproject.myapp.AppServer</mainclass></transformer></transformers></configuration></execution></executions></plugin></plugins></build>
⚠️ 注意事项总结
- ❌ 不要仅靠
“以为已配置” —— 它不执行,只管理; - ✅
是插件执行的唯一入口,必须出现在子模块 pom.xml 的 直接子节点中; - ? maven-jar-plugin 的默认 jar goal 总会在 package phase 执行,但只要 Shade 插件正确绑定,它会生成额外的 shaded jar(原 jar 仍存在,除非显式禁用);
- ? 若仍不生效,请检查 mvn help:effective-pom -Dverbose 查看实际生效的 POM 结构,确认 Shade 插件是否出现在
列表中。
遵循以上配置逻辑,即可稳定、可靠地为任意子模块生成带主类、含全部依赖的可执行 Fat Jar。










