`
ieye
  • 浏览: 32081 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

一次完整的jar包冲突解决过程

阅读更多

作为Java程序员,会经常碰到jar包冲突,特别是涉及到的外部依赖越多,冲突概率就会越大。由于我们的应用代码都是使用maven来管理的,所以依赖的解决相对比较容易。不过最近碰到的一个问题,确实经历了好多步才最终定位。

现象:应用启动过程中,spring容器启动失败,错误日志很明确,找不到CollectionUtils.isEmpty()方法,jar冲突的典型症状之一。

      首先,确认了这个类是apache的commons-collections中的工具类(在eclipse中ctrl+shift+T或者command+shitf+T寻找CollectionUtils是来自哪个jar中,同时也可以看看是不是含有这个方法),那么执行maven命令分析依赖树mvn dependency:tree -e -Dincludes=*:commons-collections*,看看应用中如何依赖commons-collections,依赖路径以及依赖版本。结果稍微出乎意料,有两个commons-collections依赖,只是groupId不同(这个时候maven是无能为力的,maven会认为这两个依赖是不同的,不会认为是一样的,因为maven对依赖的标识就是坐标,与jar中的内容无关),一个是apache-collections,另外一个是commons-collections,查看第二个中的CollectionUtils是有isEmpty方法的,第一个是没有的,而且第一个jar和第二个jar的包结构是完全相同的,apache-collections是外部系统的类库引入的,感觉好奇葩,于是果断排除之。重新查看依赖树,OK,打包重启,依然相同的错误。

       接下来,打开war包,看下WEB-INF/lib下的commons-collections确实是3.2.1,没有问题。说明war包没有问题,最起码war内不会冲突,war包没问题。那就是jboss有问题,由于之前碰到过类似的问题,直接去${jboss_home}/server/default/lib下查看,升级其中的commons-collections到3.2.1即可(应用的jar和容器中的冲突的话,以容器为主,因为容器被优先加载),无需打包,重启jboss。自信满满地以为问题解决了,结果错误还是没变。

       继续,查看jboss其他的目录,看不到commons-collections的影子。貌似到此,无路可走了。所以想想,服务器上肯定还有commons-collections-3.1存在,或许是在隐藏目录中(为毛当时没想起来用find名称搜索commons-collections)。没办法,只能通过打日志来看看CollectionUtils是从哪儿加载的了,使用了几行代码:

URL url = getClass().getClassLoader().getResource("org/apache/commons/collections/CollectionUtils.class");

LOG.error("CollectionUtils is loading from {}", url.getPath());

 重新打包部署之后,查看日志信息,显示CollectionUtils是用WEB-INF/lib/commons-collections-3.2.1.jar中加载的,真的好意外,一直都在说,jboss中的jar优先加载啊,然后才会加载war的?那为神马会显示是用war中加载的呢?而且war中的是jar包版本是OK的,至此,基本无路可走了。除非?除非那个获取加载路径的代码是有问题的,因为和我的认知确实是冲突的。于是就getResource()方法去问了web容器方面的“神”,给出的解释是这个方法返回的路径不一定是真实的加载路径,和具体的容器实现有关

       最后,貌似打开了思路,但是什么办法可以知道类的真实记载路径呢?jvm启动参数跟踪,-XX:+TraceClassLoading加在jboss其中参数中,重启jboss,查看应用启动之后的jboss日志。好吧,日志文件很大,搜索下CollectionsUtils,确实是从一个隐藏目录加载的commons-collections,问题定位到了,解决办法不用说了。

       如果前边真的用find命令搜索解决了问题,那么也不会有后边对认知的颠覆,那样还会一直认为那个api是救命稻草呢,不知道要持续到什么时候呢。另外,用find命令也只能去试探性地搜索commons-collections这个文件,但是不能排除有的类库会把commons-collections的代码内嵌在自己的jar中,这种事儿见到不少。所以走了最长的路,收获一定是最多的:)。

分享到:
评论
2 楼 lliiqiang 2014-02-27  
加载的时候一次性判断虽然不能根据需要动态反射类,但是却能够解决冲突问题,因为一次性加载就直接判断类是否冲突.
1 楼 lliiqiang 2014-02-27  
关键是jar文件的顺序,可以使用其它工程设置不同的jar包顺序解析,然后通过访问相应的类,控制包之间的类从何种包中选择.

相关推荐

    Jar包冲突问题及解决方案.docx

    ### Jar包冲突问题及解决方案 #### 一、冲突的本质 Jar包冲突问题普遍存在于Java开发过程中,特别是当项目依赖管理不当或多个库间版本不兼容时。本文将深入探讨Jar包冲突的根本原因及其解决策略。 #### 1.1 同一...

    搭建ssh完整jar包(包含Mysql资源包)

    在"搭建ssh完整jar包(包含Mysql资源包)"中,我们看到这个压缩包包含了这三大框架所需的全部jar包,共计49个,已经过筛选,去除了可能引起冲突的库。这意味着开发者无需单独下载和管理这些依赖,可以直接使用这个...

    记一次解决maven引入jar包冲突全过程;TinkConfig注册失败

    关于google的tink解密用的...如上图,utils包A下的tink中未成功引入protobuf包,判断是jar包冲突,看是否是其他的jar包也引入了其他版本的protobuf包,于是,在IDEA的命令行执行命令,mvn dependency:tree ,看是否有

    jasperreports-3.7.0的jar包

    总的来说,jasperreports-3.7.0的jar包提供了一个全面的报表解决方案,涵盖了从设计到执行的全过程,适用于各种类型的Java应用程序,尤其是需要强大报表功能的企业级应用。在使用时,需要根据项目需求选择合适的jar...

    ssh框架jar包

    在这个“ssh框架jar包”中,包含了这三个框架所需的全部jar文件,便于开发过程中一次性导入,避免了因jar包冲突带来的困扰。 1. **Struts2**:Struts2是基于MVC设计模式的Web应用框架,它继承了Struts1的优点并解决...

    友盟微信分享和微信支付冲突解决

    ### 友盟微信分享和微信支付冲突解决 在开发基于Android平台的应用时,经常会遇到集成第三方SDK(Software Development Kit)的问题。特别是在同时集成微信分享功能和微信支付功能时,可能会出现两者之间的兼容性...

    fatjar打包工具

    FatJar的核心功能是解决Java应用在运行时依赖外部库的问题,通过将所有依赖一次性打包进一个JAR,使得程序可以在没有配置Classpath的环境中执行。 FatJar基于Ant构建系统,因此它可以方便地与Java项目集成。在描述...

    如何在Ant中引入第三方Jar包

    - `<fileset>`:如果你有多个Jar包存放在同一个目录下,可以使用`<fileset>`来一次性引入: ```xml **/*.jar"/> ``` 在这里,`lib`是存放第三方Jar包的目录,`**/*.jar`表示匹配该目录下的所有Jar文件...

    fatjar_0.0.32.jar

    【fatjar_0.0.32.jar】是一款用于Java开发的工具,它主要解决了在MyEclipse和Eclipse集成开发环境中打包Fat JAR(也称为Uber JAR)的问题。Fat JAR是一种特殊的JAR文件,它包含了项目的所有依赖库,使得用户可以直接...

    ssh jar大全

    5. **冲突解决**:在Java项目中,jar包冲突是一个常见问题,不同库可能依赖于不同版本的同一个jar。使用“ssh jar大全”的好处在于,它已经预先解决了这些依赖冲突,确保所有jar包之间能够协同工作,减少开发者在...

    fatjar_0.0.32

    在Java开发过程中,有时我们需要将多个jar包整合到一个可执行的jar文件中,以便于部署和运行。这时,我们就需要用到“fatjar”这样的工具。本文将详细介绍“fatjar_0.0.32”,这是一个专门用于将第三方jar包打包进...

    用于ECLIPSE3.2中的SVN JAR包

    SVN是一种集中式版本控制系统,它允许开发者对代码进行版本管理,跟踪每一次修改,实现团队间的协同开发。通过在ECLIPSE中集成SVN,开发者可以直接在IDE内进行代码的提交、更新、查看历史记录、解决冲突等一系列操作...

    poi解析2007报错替换包

    STAX是一种处理XML的API,它允许程序以事件驱动的方式读取和写入XML,相比DOM更加高效,因为它不需要一次性加载整个XML文档到内存。 在遇到类似“解析2007报错”的问题时,可以按照以下步骤解决: 1. 首先,确认你...

    Maven安装及其使用.doc

    - **本地仓库**:Maven 使用本地仓库来存储下载的 Jar 包,确保每个 Jar 包只存储一次。 - **坐标引用**:通过在项目配置文件(pom.xml)中定义 Jar 包的坐标(groupId、artifactId、version),实现对 Jar 包的引用...

    0.14.1的libthrift.jar,以及netty-all-4.1.50.Final.jar

    - **netty-all-4.1.50.Final.jar**:这是Netty的一个版本打包,包含所有模块,方便开发者一次性引入所有功能。版本号表示这是4.1系列的第50个稳定版本,"Final"意味着这是一个正式发布版,经过了充分的测试和调试。...

    调用SVN接口所使用的jar包及源码

    在IT行业中,版本控制系统是软件开发过程中的重要工具,它帮助开发者管理代码的变更历史,协同合作,并确保代码的一致性和完整性。Subversion(简称SVN)是其中一个广泛应用的版本控制系统,而`svnkit`是Java平台上...

    jar4jar4jar4jar4jar4jar4jar4jar4jar4jar4

    【描述】:“jar4jar4jar4jar4jar4jar4jar4jar4jar4jar4”描述部分似乎没有提供具体的信息,但我们可以推断这可能是在描述一个涉及连续多次打包或链接JAR文件的过程。这可能是为了整合不同库、框架或应用程序组件,...

    项目里jar.zip

    JAR文件的主要作用是减少网络传输的时间,因为它们可以被浏览器或Java虚拟机一次性加载。此外,JAR文件还可以实现代码混淆、数字签名以及版本控制等功能。 2. **Web开发**: Web开发是指创建、设计和维护Web应用...

    maven资源包maven资源包

    Maven会自动解决依赖树,确保所有依赖项的版本都兼容,并且只下载一次,存放在用户的本地Maven仓库中,供多个项目共享。 总的来说,Maven资源包是Java开发中不可或缺的一部分,它提供了一种标准化的方式来管理和...

Global site tag (gtag.js) - Google Analytics