zoukankan      html  css  js  c++  java
  • 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


    参考:

  • 相关阅读:
    常量,基本运算符,if判断,while循环
    python解释器的垃圾回收机制,小整数池,变量的三个特性,is与==,与用户交互,数据类型的基本使用,基本运算符
    编程语言的分类,python解释器多版本共存.执行python的两种方式,变量,用户与程序交互
    编程简介
    bootstrap 无限极菜单
    JQuery lhgdialog使用
    mysql 不是主键不能删除的保护问题解决办法?
    遍历所有的选中的radio的个数和值
    MySQL 的 RowNum 实现
    Ibatis 测试出SQL
  • 原文地址:https://www.cnblogs.com/lixin-link/p/15362918.html
Copyright © 2011-2022 走看看