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 路径下:
<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> 是原始包路径,必须精确匹配(不含通配符)
• <shadedPattern> 是新路径,建议加前缀如 shaded. 或 yourapp. 避免二次冲突
• <filter> 限定 relocation 只作用于指定 artifact,防止误改其他依赖
确保 relocation 后的类能被正确调用
Shade 插件会自动修改字节码中的常量池和方法引用,让原依赖代码调用新路径下的类。但有两点必须验证:
立即学习“Java免费学习笔记(深入)”;
- 检查最终 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 处理不完善


















