一.引言
使用 spark.hadoopFile 读取 RCFile 时,报错 Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/crypto/key/KeyProviderTokenIssuer 与 Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/fs/BatchListingOperations,修改依赖解决对应问题。
二.KeyProviderTokenIssuer
由于报错原因为 java.lang.NoClassDefFoundError 而不是 NoSuchMethod,所以基本排除是依赖冲突的高低版本的问题,如果不放心也可以使用编辑器进行全局搜索,这里全局搜索是没有该类的:
编辑
确实没有该类,提高 hadoop-common 消除该报错:
<dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
此时代码已有该类:
编辑
三.BatchListingOperations
修改 pom 后再次运行任务,再次提示 NoClassDefFoundError,根据上面的经验,这里判断还是没有依赖,所以再次修改 hadoop 版本。
编辑
hadoop-common 提高至 3.3.3:
<dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>3.3.3</version> <scope>provided</scope> </dependency>
再次运行任务没有问题:
编辑
四.判断与排查
1.如何判断没有依赖还是依赖冲突
一般情况下:
NoSuchMethod -> 依赖冲突
NoClassDefFoundError ->
A. 报错有自己代码的异常栈:对应 Class / Object 初始化失败
B. 报错均为官方异常栈:无对应依赖
2.最简单的确认方式
在 idea 或者 maven-tree 中查看报错对应依赖,如果有多个,大概率是依赖冲突,如果一个也搜不到则为无对应依赖,像这样快速查找,即可确定是单个,多个还是没有对应 class。
编辑
3.如果寻找对应版本
博主一般直接将报错贴至 Bing 国际版,像上面的错就可以直接得到版本。
编辑
编辑
4.最确切的版本定位
如果要寻找项目真实的版本,可以寻找底层代码的 GitHub,查看你当前调用版本 API 所在 branch 的 pom.xml,其内部的版本即为最确切的版本。例如之前在 Spark - ml.dmlc.xgboost4j / spark 版本匹配与 NoSuchMethodError 解决 一文中我们通过排查源码 pom.xml,才最终定位到当前 spark 版本与 xgboost 指定 spark 版本不一致导致依赖冲突。
编辑