Maven包冲突导致NoSuchMethodError错误的解决办法
作者:斯通
项目清况
项目中有两个包都引用了jackson 的包且都是不再更新的版本
// jarA 包中引入 org.codehaus.jackson 包 1.8.4 版本 <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-asl</artifactId> <version>1.8.4</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.8.4</version> </dependency> //jar B 包中引入了 org.codehaus.jackson 包 1.9.13 版本 <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-asl</artifactId> <version>1.9.13</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency> // org.codehaus.jackson 包最后在 2013 年的时候发生了组织变化(fastxml) ,且后续不再维护 // 如今正确使用jackson 应该引入以下的 3 个包: <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.17.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.17.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.17.1</version> </dependency>
从上面包中看得出,项目有些年代感了(springmvc 3.x 的版本,打包成war 部署运行),本着能运行的情况下,绝不随意改动的原则,还是继续使用 org.codehaus.jackson
这个包
报错、异常
web 项目 能正常编译,运行时也正常启动,但执行到需要调用 org.codehaus.jackson 包中的某个方法时,产生运行异常:NoSuchMethodError:org.codehaus.jackson.map.ObjectMapper.setSerializationInclusion
找到报错处是 jarB 中的程序片段异常,找到对应代码中引用的包,定位后发现确实不存在这个方法,此时打开的是 1.8.4 的版本,(jarB 需要 1.9.13 版本的包)
处理冲突
找到问题了就好说,1.9与 1.8的版本应该上线兼容,则采用 1.9 的版本即可, 那么我们只需要在 jarA 中排除掉 1.8.4 的jackson 应该就能解决问题
<dependency> <groupId>org.china.xxxx</groupId> <artifactId>jarA</artifactId> <version>x.x.x</version> // 排除 ,jarA 中对低版本的引入 <exclusion> <artifactId>jackson-core-asl</artifactId> <groupId>org.codehaus.jackson</groupId> </exclusion> <exclusion> <artifactId>jackson-mapper-asl</artifactId> <groupId>org.codehaus.jackson</groupId> </exclusion> </dependency>
做了这个动作之后发现,项目中的已换成 1.9.13 版本
可以 使用 Maven Helper 工具来查看依赖冲突,exclude 包等
排除后充新编译项目启动运行,发现仍然
NoSuchMethodError:org.codehaus.jackson.map.ObjectMapper.setSerializationInclusion
进一步探究
- 编写单元测试 方法调用,发现单元测试没问题
说明问题出在 Tomcat, 编译没问题说明包引入正常(idea 中包依赖显示正常,且跟踪代码也能找到正确的包) 问题应该出在 ClassLoad → 类加在上
- tomcat 启动项 增加
-XX:+TraceClassLoading -XX:+TraceClassUnloading
tomcat 启动后发现,jackson 仍然加载 1.8.4 的版本
- 根据步骤 2 查看对应的目录发现,存在多个版本的包(但低版本的我应该排除掉了才对), 这个目录在 idea 项目的 target目录下
target/项目名称/WEB-INF/lib
结合了解到tomcat 加载 lib 目录下的包时,会按照顺序加在,且同样的包只会加在一次,所以,这里应该是优先加在了 1.8.4 所以后续引入的 1.9 就被忽略
那么问题来了-》 dependency 中 exclusion 排除了 低版本的包,是怎么又出现在 lib 中的,
发现问题
最后仔细观察 发现 jarA 是作为父项目,引入到当前项目中的
overlay 的资源会被覆盖到当前项目中,包括,WEB-INF 下的所有lib 这也是为什么在 lib 目录下仍然存在 1.8.4 版本的包. 需要在 overlay 中也将相应的包剔除
... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.2</version> <configuration> <overlays> <overlay> <groupId>com.unionman</groupId> <artifactId>unionmanframe</artifactId> <excludes> <exclude>**/jackson-core-asl-1.8.4.jar</exclude> <exclude>**/jackson-mapper-asl-1.8.4.jar</exclude> </excludes> </overlay> </overlays> </configuration> </plugin> ...
最后再次启动,类正常加载 jackson-1.9.13 包
以上就是Maven包冲突导致NoSuchMethodError错误的解决办法的详细内容,更多关于Maven导致NoSuchMethodError的资料请关注脚本之家其它相关文章!
您可能感兴趣的文章:
- 详解Matisse与Glide--java.lang.NoSuchMethodError:com.bumptech.glide.RequestManager.load
- Java异常 Factory method''sqlSessionFactory''rew exception;ested exception is java.lang.NoSuchMethodError:
- 解决启动Azkaban报错问题:java.lang.NoSuchMethodError: com.google.common.collect.ImmutableMap.toImmutableMap
- 解决 java.lang.NoSuchMethodError的错误