Exception in thread “main” java.lang.NoSuchMethodError: org.codehaus.janino.ClassBodyEvaluator.setExtendedClass(Ljava/lang/Class;)V
at org.apache.spark.sql.catalyst.expressions.codegen.CodeGenerator.org.orgapachesparksparksqlcatalystcatalystexpressionscodegencodegenCodeGenerator$$doCompile(CodeGenerator.scala:949)
看到 java.lang.NoSuchMethodError直觉就是版本问题,但是问题是不知道是哪个版本的问题。
怀疑是因为本地scala是2.11.12版本
重新装一个2.11.8版本试试
还是不行
换来回去,改出一个新错
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Incompatible Jackson version: 2.8.9
改成2.4告诉我 Jackson version: 2.4.0 to old
Jackson 大哥你到底要啥version呢
最后答案在spark目录下的jars
把version换成了一样的2.6.5
最后定位到janino.jar
pom已经改为了跟spark jars 一致的版本
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.0.8</version>
</dependency>
还是报错
最后怀疑是其他依赖包冲突
查看jar包间接依赖
mvn dependency:tree>tree.txt
[INFO] +- org.drools:drools-compiler:jar:5.0.1:compile
[INFO] | +- org.antlr:antlr-runtime:jar:3.1.1:compile
[INFO] | +- org.eclipse.jdt:core:jar:3.4.2.v_883_R34x:compile
[INFO] | - janino:janino:jar:2.5.15:compile
定位到org.drools:drools-compiler
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>5.0.1</version>
<exclusions>
<exclusion>
<groupId>janino</groupId>
<artifactId>janino</artifactId>
</exclusion>
</exclusions>
</dependency>
JAR包冲突解决方法
问题表现
系统原来可以运行, 但是引入某个jar包(为了调用某个服务)后, 所有配置/参数都正确, 但是却运行不起来, 或者报找不到类, 找不到方法等异常!
java类找不到 java.lang.ClassNotFoundException
方法不存在 java.lang.NoSuchMethodError
字段不存在 java.lang.NoSuchFieldError
类错误 java.lang.LinkageError
表面原因
war包中jar包和服务器上jar包冲突, 由于现在服务器功能越来越强大, 而引入的jar也在不断增加, 出现的冲突的可能性也越来越大, 而且正式环境复杂, 而且不能轻易修改服务器相关配置
根本原因
同一个java类存在多个jar包或类路径中, 而这大多由于使用了不同jar包版本造成.
maven管理jar包, 如果同一个Jar有多个版本是根据最短路径拉取jar包的
同一个package出现在多个jar包里面, 怎么处理?
简单的处理方法
根据报错的class名或方法名定位到可能导致冲突的jar包,jar包冲突引入有几种情况:
引入了这个jar包的多个版本,而mvn仲裁的时候取了错误的版本,这个版本本身就缺少正确的class或方法。
引入了不同坐标但是具有同名class的多个jar,mvn加载class的顺序差异会导致加载到错误的class。
通过mvn dependency:tree > tree.txt 导出全部的依赖。 可以使用 -Dverbose 、-Dincludes或者-Dexcludes参数来精确定位导致冲突的jar包。
找到需要排除的依赖jar包,通过mvn仲裁优先的方法定义正确的jar包,或者通过exclusion的方式排除错误的jar包。
温馨提示:另外在项目开发中jar尽量按需引入,系统管理起来,别什么都不管直接加包进来,这样也可以在一定程度上减少jar包冲突的风险。
避免技巧
为了减少jar包冲突, 特别是一些底层jar包, 根据最短路径方法: 最好人工指定版本, 并使用dependencyManage