<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          依賴沖突了如何解決?

          共 6259字,需瀏覽 13分鐘

           ·

          2021-10-14 19:17

          作者 | jajian

          鏈接 | cnblogs.com/jajian/p/11002521.html

          0、前言

          由于此訂閱號(hào)換了個(gè)皮膚,系統(tǒng)自動(dòng)取消了讀者的公眾號(hào)置頂。導(dǎo)致用戶接受文章不及時(shí)。可以打開訂閱號(hào),選擇置頂(標(biāo)星)公眾號(hào),重磅干貨,第一時(shí)間送達(dá)!

          1、前言

          我們程序員在開發(fā)的時(shí)候經(jīng)常會(huì)遇到各種各樣的 BUG 問題,其中大部分是業(yè)務(wù)邏輯異常,還有一些是代碼書寫不規(guī)范造成的異常。

          例如:NullPointException(NPE),IndexOutOfBoundsException 等等,其實(shí)這些我們都好定位和修復(fù)。但是還有一些運(yùn)行時(shí)異常定位起來是特別頭疼的,那就是 jar 包沖突引起的異常。

          一般程序在運(yùn)行時(shí)發(fā)生類似于 java.lang.ClassNotFoundException,Method not found: '……',或者莫名其妙的異常信息,這種情況一般很大可能就是 jar包依賴沖突的問題引起的了。

          至于為什么會(huì)發(fā)生 jar包依賴沖突?這種問題大致可以歸納為如下幾個(gè)原因:

          • 版本不匹配,高版本依賴了低版本,或者低版本依賴了高版本。例如引入第三方庫,但是第三方庫基于的是 JDK7,而你們項(xiàng)目使用的是JDK8。

          • 重復(fù)引入不同版本jar包,造成使用錯(cuò)誤。很多時(shí)候我們引入第三方輪子,它們依賴引入某個(gè)基礎(chǔ)工具使用的是 v 1.0 的 jar,但是我們項(xiàng)目中自己也引入了該 jar,但是版本是 v 2.3,這時(shí)就會(huì)造成項(xiàng)目中使用同一個(gè)組件但是依賴了兩個(gè)不同版本的jar,沖突就會(huì)發(fā)生。

          可以看到,其實(shí)總的來說 jar 包沖突的主要原因就是依賴的版本沖突。

          2、異常發(fā)生

          項(xiàng)目中需要導(dǎo)出報(bào)表,技術(shù)選型的時(shí)候,一般是選用 Apache POI,但是 POI 的使用方式比較基礎(chǔ),開發(fā)量大,容易出現(xiàn)內(nèi)存溢出的問題。

          考慮到阿里開源了一套解析和生成Excel的工具 - EasyExcel,具有避免內(nèi)存溢出OOM的情況發(fā)生,而且使用方便簡單,所以就將它引入到了我們的項(xiàng)目中,具體的使用版本是 1.0.2。

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

          而另一個(gè)模塊需要使用 POI 的將 Word 轉(zhuǎn)成 PDF 的功能,所以同時(shí)又引入了如下 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 可以發(fā)現(xiàn),阿里 EasyExcel 1.0.2 依賴的 POI 也是 3.15,所以照理說應(yīng)該是沒問題的。

          但是在接口調(diào)試的時(shí)候還是出問題了,而且異常信息很奇怪,不是看一眼就能知道問題原因的并解決的。

          Caused by: java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.getXmlStandalone()Z    at 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

          提取關(guān)鍵信息,可以看到錯(cuò)誤類型 java.lang.AbstractMethodError,這個(gè)錯(cuò)誤類型望名知義:抽象方法錯(cuò)誤。這種類型的錯(cuò)誤和我們上面說的 ClassNotFoundException 類似,很大可能就是 Jar包依賴沖突所導(dǎo)致的。

          3、異常定位

          那我們來定位下是哪個(gè) jar 包沖突了,只需要將沖突的 jar 包排除掉,留下正確的就可以了。

          我們可以看到錯(cuò)誤類型是 java.lang.AbstractMethodError,錯(cuò)誤類型后面是具體的錯(cuò)誤信息描述 :org.apache.xerces.dom.DocumentImpl.getXmlStandalone()Z,意思是在包 org.apache.xerces.dom 下的類DocumentImpl它的方法getXmlStandalone()調(diào)用出現(xiàn)了錯(cuò)誤。

          那么具體是誰在調(diào)用呢?我們在異常信息的緊密下一行可以看到如下這一行代碼:

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

          在包路徑 com.sun.org.apache.xalan.internal.xsltc.trax 下,DOM2TO 類代碼的的第377行,有個(gè)setDocumentInfo方法,我們鼠標(biāo)左鍵點(diǎn)進(jìn)去,在該行加個(gè) Debug 斷點(diǎn)。

          我們發(fā)現(xiàn)這個(gè) DOM2TO 類是 JDK1.8中 rt.jar 包里面的,具體類路徑如下:

          通過斷點(diǎn)調(diào)試得知,這個(gè) document 對(duì)象是 DocumentImpl 實(shí)例,

          這個(gè)DocumentImpl 的真實(shí)路徑也是 JDK1.8中 rt.jar 包里面的,它是 CoreDocumentImpl 的子類,CoreDocumentImpl 是接口Document 的實(shí)現(xiàn)類。

          package com.sun.org.apache.xerces.internal.dom;
          public class DocumentImpl extends CoreDocumentImpl implements DocumentTraversal, DocumentEvent, DocumentRange {
          ......}

          CoreDocumentImpl

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

          我們在 CoreDocumentImpl 類中第983行發(fā)現(xiàn)了getXmlStandalone方法。

          這時(shí)報(bào)錯(cuò)原因赤條條的擺在我們面前了,顯而易見,DOM2TO類中 setDocumentInfo 方法的參數(shù) Document 是屬于 JDK1.8 中 rt.jar 包下類路徑 com.sun.org.apache.xerces.internal.dom 下的實(shí)現(xiàn)類 DocumentImpl。而我們報(bào)錯(cuò)的信息提示中是:

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

          這個(gè) org.apache.xerces.dom.DocumentImpl 明顯不屬于我們 JDK1.8 的 rt.jar 包,而且也沒有 getXmlStandalone 這個(gè)方法。

          所以得知,我的項(xiàng)目中 jar 包依賴沖突了,我們只需要排除掉 org.apache.xerces.dom.DocumentImpl 所屬的 jar 包就可以了。如何排除呢?

          4、排除沖突

          我們在 IDEA 中雙擊 Shift 鍵,輸入 DocumentImpl,得到如下結(jié)果:

          可以發(fā)現(xiàn),這里有兩個(gè) CoreDocumentImpl,一個(gè)是我們的 JDK1.8的,一個(gè)是屬于 xerce的,而且確實(shí)在依賴的 maven jar 包中發(fā)現(xiàn)了 xercesImpl-2.4.0.jar,這個(gè) jar包就是需要排除的 jar包。

          發(fā)現(xiàn)了沖突的 jar包,我全局搜索關(guān)鍵字 xerces,并沒有發(fā)現(xiàn)哪一個(gè) pom 中有依賴的代碼,所以很可能是其他的 jar 包傳遞依賴進(jìn)來的。

          我們借助 IDEA 的 maven 工具,在 maven 欄右鍵項(xiàng)目模塊,選擇 show Dependencies 或 Ctrl + Shift + Alt + U,這時(shí)候會(huì)展示當(dāng)前模塊的 jar 包依賴圖,如下:

          雖然這里展示了很多沖突的jar包,其中紅線連接的就是沖突的jar 包,但是我們 Ctrl + F 查詢 xerces 還是沒有結(jié)果。

          所以我們需要額外的方式來解決,這時(shí)我想到了 IDEA 有個(gè)插件 Maven Helper,具體的插件下載可以參考前面的內(nèi)容,下載好插件后,我們打開 pom.xml 文件,在pom.xml 文件的左下方有個(gè) Dependency Analyzer,我們點(diǎn)擊之后顯示如下:

          • Conflicts:展示所有沖突。

          • All Dependencies as List:以列表的方式展示所有依賴。

          • All Dependencies as Tree:以樹形的方式展示所有依賴。

          我們輸入 xerces,選擇以樹形展示所有依賴,得到如下的信息顯示。

          清晰明了,原來這個(gè)罪魁禍?zhǔn)资潜?file-web-sdk 帶進(jìn)來的,我們右鍵選擇 Jump To Source或者 F4 定位到這個(gè) jar 在 pom.xml 的依賴引入位置,如下圖所示,我們通過 exclusion 標(biāo)簽排除 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>

          再次啟動(dòng)項(xiàng)目,測試接口發(fā)現(xiàn)功能正常了,整個(gè)排查過程也就結(jié)束了,IDEA的功能還是很強(qiáng)大的。

          5、總結(jié)

          很多時(shí)候的 jar 包沖突,有些是我們很容易排除,例如在pom.xml 中我們就可以發(fā)現(xiàn)一些重復(fù)引入,但是版本不相同的依賴。還有一些是其他依賴傳遞依賴進(jìn)來的,我們在 pom.xml 文件中不能很直觀的發(fā)現(xiàn),這時(shí)候我們借助工具可以發(fā)現(xiàn)這種沖突的依賴。

          但是還有一些是更隱秘的沖突,就像本文中描述的依賴沖突,這時(shí)候我們需要分析異常信息,并定位沖突的原因和找到具體沖突的依賴引入,最后將它排除就可以了。

          本文比較詳細(xì)的介紹了異常的分析和沖突的定位,以及最后的排除。類似的依賴沖突基本都可以參考上述的方式進(jìn)行排查,希望通過本篇文章對(duì)大家解決項(xiàng)目中依賴沖突有所幫助。


          怎么接私活?這個(gè)渠道你100%有用!請收藏!


          點(diǎn)個(gè)在看 
          瀏覽 60
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  99久久夜色精品国产亚洲 | sm免费观看 | www.caopeng | 国产高清无码免费视频 | 成人视频网站久久久精品网站久久久 |