作者:jajianhttp://cnblogs.com/jajian/p/11002521.html

推荐阅读(点击即可跳转阅读)

1. SpringBoot内容聚合

2. 面试题内容聚合

3. 设计模式内容聚合

4. 排序算法内容聚合

5. 多线程内容聚合

1、前言

我们程序员在开发的时候经常会遇到各种各样的 BUG 问题,其中大部分是业务逻辑异常,还有一些是代码书写不规范造成的异常。

例如:NullPointException(NPE),IndexOutOfBoundsException 等等,其实这些我们都好定位和修复。但是还有一些运行时异常定位起来是特别头疼的,那就是 jar 包冲突引起的异常。

一般程序在运行时发生类似于 java.lang.ClassNotFoundException,Method not found: '……',或者莫名其妙的异常信息,这种情况一般很大可能就是 jar包依赖冲突的问题引起的了。

至于为什么会发生 jar包依赖冲突?这种问题大致可以归纳为如下几个原因:

  • 版本不匹配,高版本依赖了低版本,或者低版本依赖了高版本。例如引入第三方库,但是第三方库基于的是 JDK7,而你们项目使用的是JDK8。
  • 重复引入不同版本jar包,造成使用错误。很多时候我们引入第三方轮子,它们依赖引入某个基础工具使用的是 v 1.0 的 jar,但是我们项目中自己也引入了该 jar,但是版本是 v 2.3,这时就会造成项目中使用同一个组件但是依赖了两个不同版本的jar,冲突就会发生。

可以看到,其实总的来说 jar 包冲突的主要原因就是依赖的版本冲突。


2、异常发生

项目中需要导出报表,技术选型的时候,一般是选用 Apache POI,但是 POI 的使用方式比较基础,开发量大,容易出现内存溢出的问题。

考虑到阿里开源了一套解析和生成Excel的工具 - EasyExcel,具有避免内存溢出OOM的情况发生,而且使用方便简单,所以就将它引入到了我们的项目中,具体的使用版本是 1.0.2。

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>1.0.2</version>
</dependency>

而另一个模块需要使用 POI 的将 Word 转成 PDF 的功能,所以同时又引入了如下 POI 的依赖:

<!-- poi utils -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.15</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.15</version>
</dependency>

我们从 Maven Repository 可以发现,阿里 EasyExcel 1.0.2 依赖的 POI 也是 3.15,所以照理说应该是没问题的。

但是在接口调试的时候还是出问题了,而且异常信息很奇怪,不是看一眼就能知道问题原因的并解决的。

Caused by: java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.getXmlStandalone()Zat com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.setDocumentInfo(DOM2TO.java:377)at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:131)at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:98)at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:693)at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:737)at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:351)at org.apache.poi.openxml4j.opc.StreamHelper.saveXmlInStream(StreamHelper.java:80)at org.apache.poi.openxml4j.opc.internal.marshallers.ZipPartMarshaller.marshallRelationshipPart(ZipPartMarshaller.java:181)at org.apache.poi.openxml4j.opc.ZipPackage.saveImpl(ZipPackage.java:560)at org.apache.poi.openxml4j.opc.OPCPackage.save(OPCPackage.java:1557)at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:248)at org.apache.poi.xssf.streaming.SXSSFWorkbook.write(SXSSFWorkbook.java:941)at com.alibaba.excel.write.ExcelBuilderImpl.finish(ExcelBuilderImpl.java:64)at com.alibaba.excel.ExcelWriter.finish(ExcelWriter.java:95)at com.pingan.haofang.creams.common.utils.ExcelUtil.writeExcel(ExcelUtil.java:71)......... 65 common frames omitted

提取关键信息,可以看到错误类型 java.lang.AbstractMethodError,这个错误类型望名知义:抽象方法错误。这种类型的错误和我们上面说的 ClassNotFoundException 类似,很大可能就是 Jar包依赖冲突所导致的。


3、异常定位

那我们来定位下是哪个 jar 包冲突了,只需要将冲突的 jar 包排除掉,留下正确的就可以了。

我们可以看到错误类型是 java.lang.AbstractMethodError,错误类型后面是具体的错误信息描述 :org.apache.xerces.dom.DocumentImpl.getXmlStandalone()Z,意思是在包 org.apache.xerces.dom 下的类DocumentImpl它的方法getXmlStandalone()调用出现了错误。

那么具体是谁在调用呢?我们在异常信息的紧密下一行可以看到如下这一行代码:

at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.setDocumentInfo(DOM2TO.java:377)

在包路径 com.sun.org.apache.xalan.internal.xsltc.trax 下,DOM2TO 类代码的的第377行,有个setDocumentInfo方法,我们鼠标左键点进去,在该行加个 Debug 断点。

我们发现这个 DOM2TO 类是 JDK1.8中 rt.jar 包里面的,具体类路径如下:

通过断点调试得知,这个 document 对象是 DocumentImpl 实例,

这个DocumentImpl 的真实路径也是 JDK1.8中 rt.jar 包里面的,它是 CoreDocumentImpl 的子类,CoreDocumentImpl 是接口Document 的实现类。

package com.sun.org.apache.xerces.internal.dom;public class DocumentImplextends CoreDocumentImplimplements DocumentTraversal, DocumentEvent, DocumentRange {......
}

CoreDocumentImpl

package com.sun.org.apache.xerces.internal.dom;public class CoreDocumentImplextends ParentNode implements Document {......
}

我们在 CoreDocumentImpl 类中第983行发现了getXmlStandalone方法。

这时报错原因赤条条的摆在我们面前了,显而易见,DOM2TO类中 setDocumentInfo 方法的参数 Document 是属于 JDK1.8 中 rt.jar 包下类路径 com.sun.org.apache.xerces.internal.dom 下的实现类 DocumentImpl。而我们报错的信息提示中是:

Caused by: java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.getXmlStandalone()Z

这个 org.apache.xerces.dom.DocumentImpl 明显不属于我们 JDK1.8 的 rt.jar 包,而且也没有 getXmlStandalone 这个方法。

所以得知,我的项目中 jar 包依赖冲突了,我们只需要排除掉 org.apache.xerces.dom.DocumentImpl 所属的 jar 包就可以了。如何排除呢?


4、排除冲突

我们在 IDEA 中双击 Shift 键,输入 DocumentImpl,得到如下结果:

可以发现,这里有两个 CoreDocumentImpl,一个是我们的 JDK1.8的,一个是属于 xerce的,而且确实在依赖的 maven jar 包中发现了 xercesImpl-2.4.0.jar,这个 jar包就是需要排除的 jar包。

发现了冲突的 jar包,我全局搜索关键字 xerces,并没有发现哪一个 pom 中有依赖的代码,所以很可能是其他的 jar 包传递依赖进来的。

我们借助 IDEA 的 maven 工具,在 maven 栏右键项目模块,选择 show Dependencies 或 Ctrl + Shift + Alt + U,这时候会展示当前模块的 jar 包依赖图,如下:

虽然这里展示了很多冲突的jar包,其中红线连接的就是冲突的jar 包,但是我们 Ctrl + F 查询 xerces 还是没有结果。

所以我们需要额外的方式来解决,这时我想到了 IDEA 有个插件 Maven Helper,具体的插件下载可以参考前面的内容,下载好插件后,我们打开 pom.xml 文件,在pom.xml 文件的左下方有个 Dependency Analyzer,我们点击之后显示如下:

  • Conflicts:展示所有冲突。
  • All Dependencies as List:以列表的方式展示所有依赖。
  • All Dependencies as Tree:以树形的方式展示所有依赖。

我们输入 xerces,选择以树形展示所有依赖,得到如下的信息显示。

清晰明了,原来这个罪魁祸首是被 file-web-sdk 带进来的,我们右键选择 Jump To Source或者 F4 定位到这个 jar 在 pom.xml 的依赖引入位置,如下图所示,我们通过 exclusion 标签排除 xercesImpl 的引入即可。

<dependency><groupId>com.xx.xx.gov.fileservice</groupId><artifactId>file-web-sdk</artifactId><exclusions><exclusion><groupId>xerces</groupId><artifactId>xercesImpl</artifactId></exclusion></exclusions>
</dependency>

再次启动项目,测试接口发现功能正常了,整个排查过程也就结束了,IDEA的功能还是很强大的。


5、总结

很多时候的 jar 包冲突,有些是我们很容易排除,例如在pom.xml 中我们就可以发现一些重复引入,但是版本不相同的依赖。还有一些是其他依赖传递依赖进来的,我们在 pom.xml 文件中不能很直观的发现,这时候我们借助工具可以发现这种冲突的依赖。

但是还有一些是更隐秘的冲突,就像本文中描述的依赖冲突,这时候我们需要分析异常信息,并定位冲突的原因和找到具体冲突的依赖引入,最后将它排除就可以了。

本文比较详细的介绍了异常的分析和冲突的定位,以及最后的排除。类似的依赖冲突基本都可以参考上述的方式进行排查,希望通过本篇文章对大家解决项目中依赖冲突有所帮助。

排除jar_通过IDEA快速定位和排除依赖冲突相关推荐

  1. 排除计算机硬件故障,如何快速准确地排除电脑硬件故障

    电脑使用久了,难免会出现各种各样的软硬件问题,而你是否会正确快速的判断出是何故障呢?今天就带你一起去看看如何排除电脑硬件故障. 如何快速准确地排除电脑硬件故障 01 现象:电脑无法开机,而且CPU风扇 ...

  2. 如何快速的解决Maven依赖冲突

    为什么会出现依赖冲突 首先要说明Maven的依赖管理,具体的可以参考这边 Maven学习--依赖管理 这篇文章,maven在依赖冲管理中有一下几个原则. 依赖是使用Maven坐标来定位的,而Maven ...

  3. Gradle 使用技巧(四) - 如何定位和解决依赖冲突

    1. 前言 随着业务的复杂度加深,我们免不了要引入许多的第三方开源库,也不可避免的会出现依赖冲突的错误.最常见的是V7.V4包之间的冲突. 2. 如何定位依赖冲突 解决依赖冲突很简单,难得是如何去定位 ...

  4. 网络故障排除工具 | 快速定位网络故障

    网络故障排除对于网络技术专家和网络工程师是颇具挑战的工作.每当添加新的设备或网络发生变更时,新的问题就会出现,而且很难确定问题出在哪里.每一位网络工程师或专家都有自己的经验和必备工具,能让他们快速定位 ...

  5. 在 windows 命令行下快速检测与排除网络故障

    电子科技大学微软技术俱乐部 梁晨 当我们组建好了一个小型局域网后,为了使网络运转正常,网络维护就显得格外重要.由于网络协议和网络设备的复杂性,许多故障解决起来绝非像解决单机故障那么简单.网络故障的定位 ...

  6. find 排除_排列五248期定位预测,大师排除两头两尾

    202247期开奖号码:9808 5 排列五头尾杀号回顾 20221期头尾杀号 开:4426 排除头:3.9 对 排除尾:3.7 对 20222期头尾杀号 开:5288 排除头:1.3 对 排除尾:0 ...

  7. 线上频繁发生Full GC 如何调优?如何快速定位OOM、cpu飙升、线程死锁等问题

    文章目录 1. jvm调优命令.工具介绍 ①:jps ②:jmap 查看应用中各实例生成情况 快速定位内存突然飙升导致的OOM异常 查看堆内存使用情况 ③:Jstack 检测线程死锁 快速定位导致cp ...

  8. Logback 快速定位用户在一次请求中的所有日志

    问题描述 最近经常做线上问题的排查,而排查问题用得最多的方式是查看日志,但是在现有系统中,各种无关日志穿行其中,导致我没办法快速的找出用户在一次请求中所有的日志. 问题分析 我们没办法快速定位用户在一 ...

  9. 如何快速定位接口响应慢问题

    如何快速定位接口响应慢问题 一.背景 在开发联调阶段发现一个接口的响应时间特别长,经常超时,囧- 本文讲讲是如何定位到性能瓶颈以及修改的思路,将该接口从 2 s 左右优化到 200ms 以内 . 二. ...

最新文章

  1. java编写数字金字塔_用JAVA写数字金字塔
  2. 河北计算机辅助普通话试题,115-河北省计算机辅助普通话水平测试培训.pptx
  3. oracle10g rman备份有效性,验证RMAN备份的有效性
  4. 中国大学MOOC-陈越、何钦铭-数据结构-2019春期末考试(题目+部分解答)
  5. java volatile lock_Java并发学习笔记 -- Java中的Lock、volatile、同步关键字
  6. Jmeter生成自动化和性能多维度测试报告(性能指标和监听器图表)
  7. oracle解锁用户实例,在Oracle 11G R2里启用示例帐户scott
  8. 数据分析数据可视化(二)
  9. Windows下kafka的下载安装
  10. android手机切换手写输入法,安卓搜狗输入法手写输入切换怎么设置
  11. 软件创新实验室:微信小程序开发——音频录制与播放
  12. 澳洲计算机信息安全专业,澳洲网络信息安全专业有哪些牛校?本科硕士有哪些方向可以选择?...
  13. li标签中hover的使用及li标签的样式
  14. Spring Boot启动参考指南(官方版)
  15. C语言学习笔记---字符处理函数getc()和getchar()函数
  16. R语言RSelenium包爬取动态网页数据前期准备(环境配置)-连载NO.01
  17. 磨金石教育摄影技能干货分享|乡愁摄影作品欣赏——传统建筑篇
  18. 鸿蒙的物联网世界之我的一天
  19. 特斯拉将粉丝创意注册为商标 包括电动皮卡版书包
  20. python(opencv) SVM 测试使用

热门文章

  1. HIVE之 DDL 数据定义 DML数据操作
  2. 第六篇:汇编基础指令讲解
  3. kubernetes资源管理
  4. CSS3制作动画的三个属性
  5. jQuery起点教程之有序化插件实例
  6. 夺命雷公狗---微信开发09----玩转单图文消息回复
  7. 2015.10.13课堂
  8. 永不改变的PCB设计黄金法则
  9. U盘/硬盘/移动硬盘专家
  10. OAuth2.0_授权服务配置_三项内容_Spring Security OAuth2.0认证授权---springcloud工作笔记141