升级JDK 17与Spark 3.3.1后出现java.lang.NoClassDefFoundError错误求助
升级JDK 17与Spark 3.3.1后出现java.lang.NoClassDefFoundError错误求助
各位大佬好!最近我把应用升级到JDK 17和Spark 3.3.1之后,碰到了一个棘手的初始化错误,折腾了好久都没解决,有没有人遇到过类似问题呀,求指点🙏
错误日志如下:
java.lang.NoClassDefFoundError: Could not initialize class org.apache.spark.sql.catalyst.expressions.VirtualColumn$ at org.apache.spark.sql.catalyst.analysis.Analyzer.<init>(Analyzer.scala:1675) at org.apache.spark.sql.internal.BaseSessionStateBuilder$$anon$1.<init>(BaseSessionStateBuilder.scala:182) at org.apache.spark.sql.internal.BaseSessionStateBuilder.analyzer(BaseSessionStateBuilder.scala:182) at org.apache.spark.sql.internal.BaseSessionStateBuilder.$anonfun$build$2(BaseSessionStateBuilder.scala:360) at org.apache.spark.sql.internal.SessionState.analyzer$lzycompute(SessionState.scala:87) ... Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.ExceptionInInitializerError [in thread "Test worker"] at org.apache.spark.sql.catalyst.parser.AbstractSqlParser.parse(ParseDriver.scala:107) at org.apache.spark.sql.catalyst.parser.AbstractSqlParser.parseMultipartIdentifier(ParseDriver.scala:67) at org.apache.spark.sql.catalyst.analysis.UnresolvedAttribute$.apply(unresolved.scala:161) at org.apache.spark.sql.catalyst.expressions.VirtualColumn$.<init>(namedExpressions.scala:436) at org.apache.spark.sql.catalyst.expressions.VirtualColumn$.<clinit>(namedExpressions.scala) at org.apache.spark.sql.catalyst.analysis.Analyzer.<init>(Analyzer.scala:1675) at org.apache.spark.sql.internal.BaseSessionStateBuilder$$anon$1.<init>(BaseSessionStateBuilder.scala:182) at org.apache.spark.sql.internal.BaseSessionStateBuilder.analyzer(BaseSessionStateBuilder.scala:182) at org.apache.spark.sql.internal.BaseSessionStateBuilder.$anonfun$build$2(BaseSessionStateBuilder.scala:360) at org.apache.spark.sql.internal.SessionState.analyzer$lzycompute(SessionState.scala:87) at org.apache.spark.sql.internal.SessionState.analyzer(SessionState.scala:87) at org.apache.spark.sql.execution.QueryExecution.$anonfun$analyzed$1(QueryExecution.scala:76)
另外说一下,我当前项目用的是Jackson 2.18版本。
我的经验分享(解决思路)
从错误栈和你的环境配置来看,Jackson版本不兼容是最可能的罪魁祸首!Spark 3.3.1官方依赖的Jackson版本是2.12.7,你直接跳到了2.18,版本差了好几个大版本,很多内部API的变化导致Spark初始化VirtualColumn类时抛出异常。
给你几个亲测有效的解决方向:
1. 降级Jackson到Spark兼容版本
把项目里的Jackson版本统一改成2.12.7,和Spark 3.3.1保持一致。
- 如果是Maven项目,在
pom.xml里硬指定版本:
<properties> <jackson.version>2.12.7</jackson.version> </properties> <dependencies> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${jackson.version}</version> </dependency> <!-- 其他Jackson模块比如jsr310也同步改版本 --> </dependencies>
- Gradle项目的话,在
build.gradle里配置:
ext { jacksonVersion = '2.12.7' } dependencies { implementation "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}" implementation "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}" implementation "com.fasterxml.jackson.core:jackson-annotations:${jacksonVersion}" }
2. 给JDK 17添加必要的模块开放权限
JDK 17是模块化的,Spark 3.3.1对模块化的适配还不够完善,需要手动开放一些JDK内部API的访问权限。在JVM启动参数里加上:
--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.sql/java.sql=ALL-UNNAMED
这个操作能解决不少JDK 17下Spark初始化的类加载问题。
3. 清理依赖缓存,重新构建
有时候本地Maven/Gradle缓存的依赖会有版本混合的情况,执行清理命令重新拉取依赖:
- Maven:
mvn clean install -U - Gradle:
./gradlew clean build --refresh-dependencies
先试试第一个方案,大部分情况降级Jackson版本就能解决问题,如果不行再叠加后面的方法~
备注:内容来源于stack exchange,提问作者Desk Reference
相关产品推荐
相关产品推荐

