如何解决jar包冲突包冲突问题

jar包冲突问题排查总结
我的图书馆
jar包冲突问题排查总结
& & 在测试脚本编写和应用部署时,经常遇到的一个问题是:java.lang.NoSuchMethodError。这个问题产生的根本原因是运行时应用加载的jar包版本不是应用代码真正需要的版本。要解决这个问题,就要让应用加载真正“HasSuchMethod"的类所在的jar包。解决这个问题,我把它归纳为以下几步:验证加载内容、查找包含该类的jar包、查找应用适用的jar版本、查看出错应用加载的jar包位置、替换错误jar包版本到需要的版本。
& &&验证加载内容
& & 通常,发生了NoSuchMethodError,在报错中我们可以查看到应用真实需要的方法和方法签名,例如如下的报错:
java.lang.NoSuchMethodError: com.taobao.eagleeye.EagleEye.rpcClientRecv(Ljava/lang/SI)V
& & 表明应用需要的是EagleEye类中的包含方法签名如:void&rpcClientRecv(String str,int i)的方法。知道了这一点,我就自然需要去看一下应用中实际加载的EagleEye是什么样的情况,rpcClientRecv方法的签名是什么样子的。
& & 要得到这些内容,可以用两个工具来获取,1是classdump工具,它通过Serviceability Agent技术在运行时dump指定的类的字节码文件。2是jdgui,这是使用得最多的反编译工具,它可以把classdump工具dump出来的字节码文件反编译成java代码,可以更直观得查看应用中加载的类是什么样子。
& &&classdump工具的使用:
& & 命令:java&-classpath&".:/opt/taobao/java/lib/sa-jdi.jar"&sun.jvm.hotspot.tools.jcore.ClassDump&16528
& & 其中-classpath把sa-jdi的jar包加入到classpath中,ClassDump 是执行字节码文件dump的main方法入口类,16528是目标进程的pid,可以用jps命令得到。
& & 这样,ClassDump会把当前加载的所有Java类都dump到当前目录下,如果有全限定名相同但内容不同的类同时存在于一个Java进程中,那么dump的时候会有覆盖现象,实际dump出来的是同名的类的最后一个。
&&&&如果需要指定被dump的类的范围,可以自己写一个过滤器,在启动ClassDump工具时指定-Dsun.jvm.hotspot.tools.jcore.filter=filterClassName,如果需要指定dump出来的Class文件的存放路径,可以用-Dsun.jvm.hotspot.tools.jcore.outputDir=path来指定,path替换为实际路径。
& & 对于上面讲的例子,我们只需要EagleEye类的内容,那么,就可以写一个FilterClass类来进行dump的过滤,写这个过滤类,需要实现sun.jvm.hotspot.tools.jcore.ClassFilter,具体实现如下图所示,InstanceKlass对应于HotSpot中表示Java类的内部对象,我们只要过滤类名以com/taobao/eagleeye的类就好。
写好了这个类之后,编译,把这个类的class文件放到要执行ClassDump命令的目录下,执行时增加如下参数:-Dsun.jvm.hotspot.tools.jcore.filter=MyFilter,ClassDump就会在当前目录dump出com.taobao.eagleeye.EagleEye类的字节码。
& & 然后使用jd-gui,jd-gui是一个绿色工具,直接打开字节码文件,可以看到rpcClientRecv方法,这里就可以看到,实际上当前jvm加载的是一个没有参数的rpcClientRecv方法。
& &&查找包含该类的jar包、查找应用适用的jar版本
& & 确认了当前出现错误的应用中确实加载了不符合要求的类之后,就需要去看一下,这个类是从哪里来的,在哪个jar包中。做这件事情比较简单,只需要去eclipse中执行ctrl+shift+t,输入类名,就可以看到当前eclipse的工程中依赖的各个版本的包含这个类的jar包。接下来你可以把各个版本的类都打开,检查这些版本的jar包中是否有符合要求的方法,即方法签名符合rpcClientRecv(Ljava/lang/SI)V的方法。方法签名识别:其中L开头,;结尾的字符串标识了一个对象类型,这里的第一个参数是java.lang.String类型,第二个参数是int类型,V表示void类型返回。详细的jvm中字段类型和方法签名表示见下图:
& & 通过这个步骤,我们知道了实际上我们的应用需要什么版本的jar包,那么,接下来自然就会想要知道应用当前加载的是什么版本的jar包,又是在哪里加载进来的。
& &&查看出错应用加载的jar包和jar包位置
& &&在这个步骤,要想知道应用加载的是jar包的什么版本,需要使用jvm类加载跟踪器这个工具,这是一个基于java agent、instrument的,用于排查jar包冲突、类冲突、类版本冲突、NoClassDefFoundError、ClassNotFoundException、NoSuchMethodError&等类加载相关问题的辅助工具。这个工具的能够定时得把新加载入虚拟机类个jar包等数据输出到指定的html文件中。
& & 工具的使用方式是:首先,下载得到jvminspect.jar;其次,修改目标应用的jvm配置,在jvm参数上增加如下的配置:JAVA_OPTIONS=$JAVA_OPTIONS
-javaagent:jvminspect.jar=outputfile=jvm.inspect.output,flushIntervalSecond=300 -DHtmlFlusher.enableHyperlink=false;其中jvminspect.jar是下载得到的工具jar包,jvm.inspect.output是输出的文件地址,flushIntervalSecond参数指定的是定时刷新的时间间隔。增加了这个参数之后重启,就可以在jvm.inspect.output文件中查看这个jvm进程加载类的情况了。
& & 我们关心的是出现NoSuchMethodError&所在的类,在这个例子中,这是com.taobao.eagleeye.EagleEye类,在输出的文件中我们可以看到这个类被jvm从jar包的哪个版本中加载,jar包的物理位置等信息。
& & 知道了这些信息,我们就很清楚得能够确定问题的原因。
& &&替换错误jar包版本到需要的版本
& &&知道应用在那里加载了不期望被加载的jar包,我们就可以着手让应用把需要加载的正确版本包加载进来。不同的场景可以做不一样的操作,比如应用的war包中本身加载了错误版本的jar包,那你需要做的是修改应用的pom文件进行重新打包,把正确的jar包依赖到war包中;如果是由于某些环境的原因,classpath中存在了两个不同版本的jar包,那你就可以根据前面几步得到的信息,把错误版本(导致应用报NoClassDefFoundError、ClassNotFoundException、NoSuchMethodError等错)的版本删除,留下应用代码实际上依赖的jar包。
TA的最新馆藏
喜欢该文的人也喜欢在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
我有一个问题:一般是在项目目录有一个package.json文件,里面有要引入的包,执行安装后,依赖的包会被下载到node_modules目录下面,但是如果包之间相互依赖,而出现依赖相同的包,但是不一样的版本,那怎么办呢,这不就冲突了吗?
比如我要引入A包和B包,他们又同时依赖C包,A依赖C 1.0.0版本,B依赖C 2.0.0版本,那这样C包不冲突了吗,如果node_modules目录下面的包目录是带版本号就好了,不然可怎么办呢?
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
npm 已经帮你解决了这些问题,你不用担心,只管用就好了。
npm2 是把所有依赖依次安装到模块目录下的 node_modules 这也导致了很多时候win下目录过深无法删除。npm3 平行安装依赖,但不同版本依然安装到自己模块下的 node_modules 同时会创建一个带版本号的目录到根 node_modules 下。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
run cnpm install, 然后看看你的node_modules你就发现如何解决的说的问题,即peer dependencies的问题。 安装不同的版本,并且用软链的方式解决。
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。在使用maven开发项目的过程中,经常会遇到jar包重复加载或者jar包冲突的问题的,但是由于有些jar是由于maven的依赖加载自动加载进来的,
而不是开发者自己配置的,特别是当项目中pom中配置的...
Maven项目的pom文件中的显示声明的依赖jar,会隐式依赖一些别的第三方jar,这些隐式的jar有可能会与其它的隐式依赖的jar或显示声明的jar冲突,造成一些功能不能正常执行。这时,我们可以通过...
Maven解决jar包冲突
使用maven最烦人的可能就是类包之间的版本冲突引发的问题了,类包冲突的一个很大的原因即产类包之间的间接依赖引起的。每个显式声明的类包都会依赖于一些其它的隐式类包,这些隐式的类包会被maven间接引入...
一、Maven简介
Maven是一个跨平台的项目管理工具。作为Apache组织的一个颇为成功的开源项目,其主要服务于基于Java平台的项目创建,依赖管理和项目信息管理。
二、Maven的依赖管理
项目中,经常会遇到ClassNotFound,NoSuchMethod异常,第一反应往往是类路径不对,jar没有正确的引用。第一步判断jar是否加载,还是 加载的jar由于maven依赖管理存在传递依...
见到如下错误,可以想到是不是jar包冲突
1.java.lang.NoSuchMethodError
2.java.lang.ClassNotFoundException
3.java.lang...
Maven对于新手来说是《步步惊心》,因为它包罗万象,博大精深,因为当你初来乍到时,你就像一个进入森林的陌生访客一样迷茫。
Maven对于老手来说是《真爱配方》,因为它无所不能,利如刀锋,使用...
我相信,来到这里的你一定曾经被maven的jar包冲突困扰过。现在,阿福带着你使用IDEA彻底结局后顾之忧!工具
众所周知,IDEA为我们提供了maven视图,让我们...
pom中指定httpclient-4.4.jar,但实际打包后加载的是httpclient-4.3.6.jar,后来发现是pom中配置的打包插件maven-assembly-plugin版本过低导致的...
他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)该文件包与具有同一名称的现有文件包存在冲突,怎么解决?_360社区
绑定手机号
应国家法规对于账号实名的要求,请您在进行下一步操作前,需要先完成手机绑定 (若绑定失败,请重新登录绑定)。
不绑定绑定手机号
应国家法规对于账号实名的要求,如不绑定手机号,则只能浏览论坛,无法进行发帖、评论、回复、点赞等相关操作 (若绑定失败,请重新登录绑定)。
确定绑定手机号
反馈360产品问题,
Screenshot_-13-53-55.png (91.19 KB)
13:56 上传
更新社区就安装不了了。不知道怎么解决了!
我还卸载重装呢,没用,只好下载历史版本
来自360手机 N5(360社区3.2.6版)
历史版本哪里下?&
回复PHP小吴:在手机助手搜360社区,然后翻到最下面可以看到历史版本&
回复圈的粉:好像修复了&
我就奇怪了,攻城狮推送软件时,自己都不验证一下吗?
来自360手机 N5(360社区3.2.6版)
您好,此问题工程师已经在解决了,感谢您的反馈。
来自360手机 N5(360社区3.2.7版)
来自360社区WAP端
360n5s 一样还是这样呀
这个我也是啊,手机推送出来,手贱点了,就出这个问题了。
LV1.上等兵
来自360社区WAP端
来自360社区WAP端
热门推荐最新主帖
360社区客户端下载博客分类:
转载请注明出处:
描述一下具体场景:
环境:本地开发环境,windows7+Eclipse+HSF Jetty(HSF Jetty作为启动容器)
Defensor在进行增量覆盖率功能开发时,出现了一个诡异的问题————代码运行阶段,对一个类中的方法进行调用,报如下错误信息:
分析&解决过程:
1、正常情况应该调用tcc-emma-3.2.0.jar(对应本地tcc-emma工程)中的reportCommand类,此类中确实存在getProjectCoverageFromThread()方法2、那为什么会报找不到此方法?第一感觉,Jar包冲突了。3、在调用处的上方添加如下语句
reportCommand.class.getProtectionDomain().getCodeSource();
注:此行代码含义为————真实加载的具体类的路径信息。执行到上面的代码,通过eclipse的Inspect可以看到:真实加载的类路径为:
D:\.m2\repository\com\taobao\test\tcc-maven-plugin\1.0.8-SNAPSHOT\tcc-maven-plugin-1.0.8-SNAPSHOT.jar
4、目前为止,已经分析出确实是Jar包冲突问题导致运行时加载了错误的类。但是这个错误的jar包是在父工程pom依赖进来,且pom中的配置为scope=test,也就是说只有在构建工程的测试阶段才会加载此jar包,而在工程提供服务的运行阶段是不会加载此Jar的。并且通过查看最终编译打出的war包,确实也没有此jar。5、为什么会在运行期间加载了scope=test的Jar包里的类呢?分析到这里,聪明的读者应该会想到是Eclipse的问题所导致,它将测试阶段引用到的jar包也加入进了运行期class path中,而且加载的优先级高于tcc-emma工程中的同名类。6、尝试了多种方法,均无法将tcc-maven-plugin-1.0.8-SNAPSHOT.jar从加载过程中移除。最终,通过调整Eclipse中的Build class path顺序解决了这个问题,也就是明确告诉容器启动时优先加载tcc-emma工程中的同名类。见下图:
PS: 查看class真实归属的jar包位置
getClass().getClassLoader().getResource(getClass().getName().replace(, ) + )
转载请注明出处:
zhangym124
浏览: 254079 次
来自: 杭州
可以参考最新的文档:如何在eclipse jee中检出项目并转 ...
snowfigure 写道我专门登陆上来,就是想问问,这个Ve ...
我专门登陆上来,就是想问问,这个Version有啥鸟用?定义完 ...
引用整个包就好了,不用具体类
至于大数据量时导致图表渲染慢的问题,可以通过改变业务逻辑及交互 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 如何解决dhcp冲突问题 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信