Java版本升级后Beam测试出现Scala/GenMap类缺失报错求助
解决Java 8升级到11/17后Beam测试中Jackson Scala模块的GenMap依赖冲突
问题背景
将项目从Java 8升级到11/17后,执行Beam测试初始化TestPipeline时触发java.util.ServiceConfigurationError,根源是java.lang.NoClassDefFoundError: scala/collection/GenMap。代码未直接调用GenMap,但Jackson的Scala模块默认加载时依赖该类——而GenMap在Scala 2.12及以后版本已被移除,手动添加scala-library:2.12.9依赖后问题仍未解决。
报错堆栈
java.util.ServiceConfigurationError: com.fasterxml.jackson.databind.Module: Provider com.fasterxml.jackson.module.scala.DefaultScalaModule could not be instantiated at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:582) at java.base/java.util.ServiceLoader$ProviderImpl.newInstance(ServiceLoader.java:804) at java.base/java.util.ServiceLoader$ProviderImpl.get(ServiceLoader.java:722) at java.base/java.util.ServiceLoader$3.next(ServiceLoader.java:1395) at com.fasterxml.jackson.databind.ObjectMapper.findModules(ObjectMapper.java:1131) at org.apache.beam.sdk.testing.TestPipeline.<clinit>(TestPipeline.java:253) . . . Caused by: java.lang.NoClassDefFoundError: scala/collection/GenMap at com.fasterxml.jackson.module.scala.modifiers.ScalaTypeModifier.<init>(ScalaTypeModifier.scala:15) at com.fasterxml.jackson.module.scala.modifiers.ScalaTypeModifierModule.$init$(ScalaTypeModifier.scala:54) at com.fasterxml.jackson.module.scala.DefaultScalaModule.<init>(DefaultScalaModule.scala:18) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at java.base/java.util.ServiceLoader$ProviderImpl.newInstance(ServiceLoader.java:780) ... 61 more
触发代码
public final transient TestPipeline pipeline = TestPipeline.create();
解决思路与方案
1. 对齐Jackson Scala模块与Scala版本兼容性
问题核心是旧版Jackson Scala模块依赖Scala 2.11及以前的GenMap类,而你引入的Scala 2.12已移除该类,仅添加Scala依赖无法解决版本不匹配问题。需升级Jackson Scala模块到支持Scala 2.12的版本:
- Jackson Scala模块从2.9.x版本开始支持Scala 2.12,建议使用与Jackson核心库版本一致的稳定版(如2.15.x)。
- 在
build.gradle中明确指定兼容的依赖,注意artifactId需带_2.12后缀(对应Scala 2.12):dependencies { // 统一Jackson系列版本,确保兼容Scala 2.12 implementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-scala_2.12', version: '2.15.2' implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.15.2' implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.15.2' implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.15.2' // 你的Scala依赖 implementation group: 'org.scala-lang', name: 'scala-library', version: '2.12.9' }
2. 排查依赖树,排除旧版Jackson Scala模块
部分依赖(如旧版Beam)可能间接引入了不兼容的Jackson Scala模块,需通过依赖树排查并排除:
- 执行Gradle命令查看依赖树:
./gradlew dependencies --configuration testRuntimeClasspath | grep jackson-module-scala - 找到引入旧版本的依赖,在
build.gradle中排除:dependencies { testImplementation('org.apache.beam:beam-sdks-java-core:2.48.0') { exclude group: 'com.fasterxml.jackson.module', name: 'jackson-module-scala' // 其他引入旧版的依赖同理排除 } }
3. 临时禁用Jackson自动加载模块(应急方案)
若暂时无法升级依赖,可通过系统属性阻止Jackson自动加载DefaultScala模块(Beam初始化时会调用ObjectMapper.findModules()):
static { // 禁用自动发现模块 System.setProperty("com.fasterxml.jackson.databind.ObjectMapper.disableDefaultModules", "true"); // 手动注册必要模块(根据实际需求调整,避免影响Beam功能) ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new Jdk8Module()); }
⚠️ 此方案可能影响Beam内部序列化逻辑,仅作为临时应急使用,优先推荐版本对齐方案。
4. 升级Beam到兼容Java 11/17的版本
确保使用的Beam版本支持目标Java版本:
- Beam 2.30+支持Java 11,Beam 2.46+支持Java 17
- 升级Beam版本可自动解决部分依赖兼容性问题,减少手动调整成本
内容的提问来源于stack exchange,提问作者Eric Kolotyluk
相关产品推荐
相关产品推荐

