Maven 同一依賴多版本共存



2021/11/4 更新,可以使用maven-shade-plugin插件解決,更方便並且不用單獨下載jarjar.jar處理。
這篇博客


先說遇到的問題:

項目本身使用了 Apache poi 3.17 作為excel導出的依賴(既存功能),后來又引入了word生成工具poi-tl 1.10.0版本,使用的poi是4.1.2,導致依賴沖突。
具體體現是編譯無問題,運行時poi-tl出現ClassNotFoundException異常(因為實際使用的是3.17)。

首先想到的是排包,使用高版本依賴,但是經測試發現使用4.1.2時原本的excel功能有問題,使用3.17的時候word功能有問題,即poi 3.17、4.1.2都需要!

解決方案:
使用jarjar對依賴4.1.2的jar包修改包名,同時poi-tl也以相同方式修改包名

首先是jarjar工具的下載,官網的下載地址是這個GoogleCode

再說使用方式:

把下載的jarjar-1.4.jar包放在英文目錄下,同時把要修改的poi-4.1.2.jar也放在相同目錄
新建rule.txt,寫上rule org.apache.poi.** com.apache.poi.@1,這個是改命規則,即把org.apache.poi.**的全改成com.apache.poi.**,其中的@1代表匹配第一個*或者**,如果后面還有,就使用@2、@3……

可以先執行命令java -jar jarjar-1.4.jar strings poi-4.1.2.jar查看是否可以正確讀取包名。
然后執行java -jar jarjar-1.4.jar process rule.txt poi-4.1.2.jar poi-4.1.2-new.jar
代表以rule.txt的規則修改poi-4.1.2.jar,生成的文件名為poi-4.1.2-new.jar,新文件名隨意。

如果你按步驟到這里,很可能發現第一條命令執行出現null異常,第二條命令生成的jar包里面並沒有修改成功

因為官網下載的jarjar.jar不支持修改jdk1.8的jar包!

后來翻官網的issues發現有人提到這個問題

解決方式就是下載jarjar的源碼,替換里面的asmasm-common兩個依賴,我換成了5.0.4,然后修改build.xml中這兩個版本號,使用ant重新打包

這里放個重新打包好的jarjar包:jarjar-1.4-fixed.jar

后來發現github上的代碼已經更新了依賴,這個是地址

后面的問題就好解決了,使用這個jar包分別對poi-4.1.2.jarpoi-tl-1.10.0.jarpoi-ooxml-4.1.2.jarpoi-ooxml-schemas-4.1.2.jar執行上面第二個命令,最后把新打的jar包作為第三方依賴添加到項目里面(后面兩個依賴應該不需要修改,但是我實際的操作是一塊改了,沒有實驗不改的情況)

實際最后運行的時候仍然會出現找不到類的情況,不過肯定不是poi里面的類了,這時只需要把缺少的jar包引入進來就行。

順便附一個maven項目中引入第三方依賴的方式,以及讓其打包的配置方式:
首先在src的同級目錄創建一個lib的文件夾,放入jar包然后引用

<dependency>
    <!--自定義(隨便填)-->
    <groupId>com.apache</groupId>
    <!--自定義(隨便填,但需確保不重復)-->    
    <artifactId>poi</artifactId>
    <!--自定義(隨便填)-->    
    <version>4.1.2</version>
    <!--system,類似provided,需要顯式提供依賴的jar以后,Maven就不會在Repository中查找它-->
    <scope>system</scope>
    <!--項目根目錄下的lib文件夾下-->
    <systemPath>${basedir}/lib/poi-4.1.2-new.jar</systemPath>
</dependency>

這種方式需要對打包進行配置:

<build>
    <!--    第三方包打包    -->
    <resources>
        <resource>
            <directory>lib</directory>
            <targetPath>/BOOT-INF/lib/</targetPath>
            <includes>
                <include>**/*.jar</include>
            </includes>
        </resource>
    </resources>
</build>

另一種方式:
把jar包安裝到本地倉庫:
mvn install:install-file -Dfile=poi-4.1.2-new.jar -DgroupId=com.apache -DartifactId=poi -Dversion=4.1.2 -Dpackaging=jar

然后就可以直接引用:

<dependency>
    <groupId>com.apache</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>

順便,貼個沒有什么關系的東西:
Maven可以以在groupId后面加.的形式引入多個同名不同版本的jar包,參見stackOverflow


參考:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM