Maven 包冲突导致 NoSuchMethodError

项目清况

项目中有两个包都引用了jackson 的包且都是不再更新的版本

javascript 复制代码
// 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 应该就能解决问题

xml 复制代码
<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

进一步探究

  1. 编写单元测试 方法调用,发现单元测试没问题

📖 说明问题出在 Tomcat, 编译没问题说明包引入正常(idea 中包依赖显示正常,且跟踪代码也能找到正确的包) 问题应该出在 ClassLoad → 类加在上

  1. tomcat 启动项 增加 -XX:+TraceClassLoading -XX:+TraceClassUnloading tomcat 启动后发现,jackson 仍然加载 1.8.4 的版本
  1. 根据步骤 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 中也将相应的包剔除

xml 复制代码
...
<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 包

相关推荐
一弓虽2 小时前
maven学习
java·学习·github·maven
秋说3 小时前
【Java开发指南 | 第三十五篇】Maven + Tomcat Web应用程序搭建
java·tomcat·maven
我命由我123453 小时前
Java Maven 项目问题:com.diogonunes:JColor:jar:5.5.1 was not found in...
java·开发语言·java-ee·maven·intellij-idea·jar·intellij idea
银迢迢18 小时前
javaweb:Maven、SpringBoot快速入门、HTTP协议
java·maven
Alt.918 小时前
JavaWeb基础一(Tomcat、Maven)
tomcat·maven·web
Mr_sun.20 小时前
day18-后端Web开发——Maven高级
android·前端·maven
胖橘1 天前
Maven项目Parent,可以试试用这个代替 Spring Boot Parent
后端·maven
码农liuxin1 天前
Maven仓库加载顺序详解:settings.xml配置优先级解析
java·后端·maven
sakoba1 天前
Maven私有仓库Nexus Repository Manager 3.52的Windows 64
java·maven
LLLLLindream2 天前
3.5 SpringBootWeb案例
spring boot·spring·maven