千家信息网

Java类加载器与类冲突怎么解决

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,这篇文章主要介绍了Java类加载器与类冲突怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java类加载器与类冲突怎么解决文章都会有所收获,下面我们一起来看看吧。在
千家信息网最后更新 2025年01月31日Java类加载器与类冲突怎么解决

这篇文章主要介绍了Java类加载器与类冲突怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java类加载器与类冲突怎么解决文章都会有所收获,下面我们一起来看看吧。

在同一个项目中,包含了一个类库的两个不同版本

这个时候,可能就会遇到奇怪的问题

  • 代码的逻辑不符合预期

  • 出现NoSuchMethodError

  • ...

先说结论,出现这些问题,不用怀疑,一定是当前使用的class版本和你预期的不一致。

这里我们以 apache 的 commons-codec类库来分析问题场景。

在实现一个功能的时候,你通过maven引入了这个库的依赖:

commons-codec

commons-codec

1.10

此时,在代码里使用了类库内处理Base64的一个类,有一个这样的实现

public static byte[] decodeBase64(String base64String) {
return (new Base64()).decode(base64String);
}

然后没多久,系统中新增其它的功能,和其他系统对接的时候,引入了一个依赖。当我们高高兴兴的完成了任务,提交代码时,某天会遇到QA提了一个问题,XX功能现在不可用。

什么情况,WTF?

然后重跑功能,果不其然。什么情况。原来我们之前使用的commons-codec-1.10版本,并没有被使用,而是使用了com.springsource.org.apache.commons.codec-1.3.0版本。

什么情况?

我们在接入其他系统的时候,引入了一些依赖,而这其中他会依赖一个


org.apache.commons
com.springsource.org.apache.commons.httpclient

而他,会把上面的com.springsource.org.apache.commons.codec-1.3.0引进来。

此时,系统中就会有两个关于commons-codec的包。

而旧版本的对应Base64的类,只支持传入一个数组,不支持String

难道Maven这么傻,不会解决一下?

他会根据引入的版本,使用的maven的版本,从而选择是根据依赖声明的前后顺序或者是nearest来使用。但这个解决不了我们上面的问题,因为maven对于同一个groupId和artifactId才会使用上面这个依赖机制,所以相同的groupId和artifactId的依赖,会直接忽略,最终只使用一个。依赖树上可以看了出来:

看上面的提示omitted for duplicate。而上面关于codec的依赖,是因为artifactId被换成了org.springsource.org.apache.commons,这样maven的机制就不会生效,导致项目里出现了两个codec的jar。而且,codec.jar虽然对于org.springsource这个指定的,虽然artifactId是这个,但里面的包名还是一样样的org.apache.commons,所以是相同于两个一模一样的Jar,只是版本不同。

这个时候,到了类加载器上场的时候了。类加载器在加载类,初始化的时候,会需要加载当前class依赖的类,此时,由于依赖低版本codec的class先被加载,从而导致低版本的codec被加载。

等后面再需要codec的地方又需要类的时候,此时虽然WebappClassloader可以子优先加载,对于不同的应用进行资源隔离,但是对于同一个应用内的相同package的类,是不会重复加载的。此时,有相同的请求到来时,从已经加载的资源中找到了低版本的codec,就直接用了,而这个类里没有我们要调用的方法,就出现了熟悉的NoSuchMethodError。

解决

问题了解清楚了,那该怎么解决呢,引入一个依赖的时候,总不能一个个的去查看jar的pom声明。

出现了上述问题时,如果不是使用maven管理依赖的,像之前SSH那种一下添加一堆jar到lib目录的时候,确定了对应的问题jar后,直接删除就好,简单直接。

如果是用maven管理依赖,就需要了解,是请把这小子带到这儿的。这个时候,使用maven的命令工具:

mvn dependency:tree

然后把结果生成到一个文件中,就可以查看引入冲突的jar是谁引进来的,查明真相后,就把依赖排除出去,

类似这样:



com.xxx
xxx
1.0.4





org.apache.commons
com.springsource.org.apache.commons.codec








关于"Java类加载器与类冲突怎么解决"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"Java类加载器与类冲突怎么解决"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

时候 版本 问题 冲突 两个 功能 系统 不同 相同 代码 情况 知识 面的 内容 机制 篇文章 资源 项目 应用 支持 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 商丘网络技术开发有限 如何通过服务器访问下一级网络 山东商机互联网科技烟台 考题大专网络技术 郴州计算机软件开发培训机构 河东区企业网络技术不二之选 落实网络安全主体责任制督查检查 lol无法链接服务器 戴尔500w服务器电源启动 软件开发属于服务增值税吗 数据存储服务器 南通亿信网络技术有限公司 济南软件开发公司哪家好 软件开发不上培训班 安卓软件开发版本管理软件 我们的个人电脑数据库是正版吗 实名认证服务器 打不开代理服务器 网络安全与管控专业 软件开发高端人才上班 小米软件开发十年工作经验多少钱 自动查找数据库数据到相应表格 网络安全法的开始时间 百单网互联网科技招聘 计算机网络技术是前端吗 榴莲视频app下载安装服务器 jsp获得服务器ip 关于amd服务器提问 ff14怎么进不了服务器 一台服务器可以装多少个小程序
0