datasyslab geotools-wrapper引发NoSuchFieldError: JAVA_17问题及依赖疑问
Spark加载geotools-wrapper引发的NoSuchFieldError及版本兼容问题
问题场景
执行以下spark-shell命令加载geotools-wrapper库时触发NoSuchFieldError: JAVA_17错误:
spark-shell --driver-memory 5G --executor-memory 5G --num-executors 1 --executor-cores 5 --conf 'spark.driver.extraClassPath=/home/hadoop/segy_processor_libs/libs/geotools-wrapper-1.5.0-28.2.jar'
错误栈:
java.lang.NoSuchFieldError: JAVA_17 at org.apache.spark.util.ClosureCleaner$.getFinalModifiersFieldForJava17(ClosureCleaner.scala:424) ... 47 elided
原因分析:geotools-wrapper内置的org.apache.commons.lang3版本较旧,缺失JavaVersion.JAVA_17定义;未引入该库时,Spark自身依赖的commons-lang3版本包含该字段,导致类加载冲突。
问题解答
1. 如何解决NoSuchFieldError?是否需要排除org.apache.commons.lang3依赖?
需要排除geotools-wrapper中的org.apache.commons.lang3依赖,这是解决该冲突的直接方案。
在SBT构建文件中,引入geotools-wrapper时添加排除规则:
libraryDependencies += "com.example" % "geotools-wrapper" % "1.5.0-28.2" exclude("org.apache.commons", "commons-lang3")
原理:Spark本身依赖的commons-lang3版本已包含JAVA_17字段,排除geotools-wrapper带来的旧版本后,Spark会使用自身的依赖版本,避免类覆盖导致的字段缺失问题。
也可通过强制指定commons-lang3版本到包含JAVA_17的版本(如3.12.0及以上)解决,但排除依赖的方式更直接,能彻底避免版本冲突。
2. 混用Sedona 1.5.0与依赖1.3.1-incubating的geotools-wrapper是否会引发问题?
大概率会引发兼容性问题,原因如下:
- API变更:Sedona 1.5.0相对于1.3.1-incubating可能存在API移除、修改或新增,geotools-wrapper基于旧版本开发的调用逻辑可能失效,触发
NoSuchMethodError或ClassNotFoundException。 - 依赖冲突:两个版本的Sedona可能依赖不同版本的Spark、commons-lang3等基础库,进一步加剧类加载冲突。
- 行为不一致:部分功能的底层实现逻辑可能在新版本中调整,导致geotools-wrapper的输出结果不符合预期。
如果必须混用,建议先完成以下验证:
- 运行核心业务逻辑,检查是否有异常抛出;
- 对比Sedona 1.3.1和1.5.0的官方文档,确认geotools-wrapper用到的API是否兼容;
- 若发现兼容性问题,优先寻找适配Sedona 1.5.0的geotools-wrapper版本,或自行修改geotools-wrapper的依赖版本并重新构建。
内容的提问来源于stack exchange,提问作者Mahadi Siregar
相关产品推荐
相关产品推荐

