maven shade plugin 的 relocation 功能核心是依赖隔离而非单纯打包,即通过精准重命名冲突类的包路径(如将 org.apache.kafka.connect → shaded.org.apache.kafka.connect),并限定作用于特定 artifact,实现私有化封装,避免与运行时环境中的同名类冲突。

用 Maven Shade Plugin 的 relocation 功能解决类名冲突,核心不是“打包”,而是“隔离”——把有冲突的依赖私有化重命名,让它和外部环境互不干扰。
明确要 relocation 的目标类和来源
先定位冲突根源。比如报错 NoClassDefFoundError: org/apache/flink/cdc/connectors/shaded/org/apache/kafka/connect/json/JsonConverter,说明 FlinkCDC 内部用了 Kafka Connect 的类,但被 Paimon 或 Flink 运行时自带的旧版 Kafka 类覆盖了。这时不能简单排除依赖,而应锁定 FlinkCDC 所需的那套 Kafka Connect 类(通常是它 shaded 后的内部副本),对其做 relocation。
- 运行
mvn dependency:tree -Dincludes=org.apache.kafka:kafka-connect-api查看哪些模块引入了 Kafka Connect 及其版本 - 检查 FlinkCDC 的 jar 包内容:
jar -tf target/your-app-1.0.jar | grep "kafka/connect",确认它自带哪些类路径 - 重点识别冲突类的原始包名,例如
org.apache.kafka.connect.json或com.fasterxml.jackson.databind
在 pom.xml 中配置 relocation 规则
relocation 不是全局重命名,而是精准作用于特定依赖的特定包。以下配置将 FlinkCDC 依赖中所有 org.apache.kafka.connect 下的类,移到 shaded.org.apache.kafka.connect 路径下:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
<plugin><groupid>org.apache.maven.plugins</groupid><artifactid>maven-shade-plugin</artifactid><version>3.5.2</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><relocations><relocation><pattern>org.apache.kafka.connect</pattern><shadedpattern>shaded.org.apache.kafka.connect</shadedpattern></relocation><relocation><pattern>com.fasterxml.jackson.databind</pattern><shadedpattern>shaded.com.fasterxml.jackson.databind</shadedpattern></relocation></relocations><filters><filter><artifact>org.apache.flink:flink-connector-cdc-base</artifact><includes><include>org/apache/kafka/connect/**</include><include>com/fasterxml/jackson/databind/**</include></includes></filter></filters></configuration></execution></executions></plugin>
关键点:
• <pattern></pattern> 是原始包路径,必须精确匹配(不含通配符)
• <shadedpattern></shadedpattern> 是新路径,建议加前缀如 shaded. 或 yourapp. 避免二次冲突
• <filter></filter> 限定 relocation 只作用于指定 artifact,防止误改其他依赖
确保 relocation 后的类能被正确调用
Shade 插件会自动修改字节码中的常量池和方法引用,让原依赖代码调用新路径下的类。但有两点必须验证:
- 检查最终 fat jar 中是否真的生成了重命名后的 class 文件:
jar -tf target/your-app-1.0.jar | grep "shaded/org/apache/kafka/connect" - 确认 FlinkCDC 的核心类(如
DebeziumDeserializationSchema)反编译后,其 import 和 method call 是否已指向shaded.org.apache.kafka.connect - 若使用反射(如
Class.forName("org.apache.kafka.connect.json.JsonConverter")),需同步改写为shaded.org.apache.kafka.connect.json.JsonConverter,否则 relocation 无效
避免常见陷阱
relocation 看似简单,但几个细节处理不好就会失效:
- 不要对整个
org.apache或com.fasterxml大范围 relocation,容易破坏其他正常依赖 - 如果多个依赖都含相同冲突包(如两个 connector 都用了不同版 Jackson),需分别为它们配置独立 relocation,且新路径不能重复
- 注意资源文件(如
META-INF/services/)也需要 transformer 合并,否则 SPI 机制失效;加上ServicesResourceTransformer - shade 插件版本建议 ≥3.4.0,老版本(如 3.1.x)对 Java 17+ 的 module-info.class 处理不完善
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










