之前我写了一个使用jarjar.jar重命名包名来解决maven依赖版本冲突的问题,今天逛V2EX的时候看到有人提到maven-shade-plugin插件,就亲自试了下,发现的确非常方便,因此做下记录。

问题描述

首先说明遇到的问题:项目中已经存在poi 3.17的依赖,而poi-tl最低poi版本4.12,将项目中已有的3.17升级到4.12时,旧代码出错,但是不升级就无法使用poi-tl。

如果一个版本兼容另一个版本,只需要使用exclusions标签排包即可

其中pom.xml示例如下:

<dependencies>
    <!-- 项目中已经引用3.17 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.17</version>
    </dependency>
    <!-- 这次新加的功能需要使用poi-tl,最低poi版本4.12 -->
    <dependency>
        <groupId>com.deepoove</groupId>
        <artifactId>poi-tl</artifactId>
        <version>1.10.0</version>
    </dependency>
</dependencies>

解决思路

我们要做的就是把poi-tl中的高版本poi包改个名字,同时poi-tl中引用的地方也改名(自动),并且代码中用高本版的地方也改个名(手动)。

解决方法

  1. 创建一个空maven项目,引入poi-tl的依赖:
<dependencies>
    <!-- 这次新加的功能需要使用poi-tl -->
    <dependency>
        <groupId>com.deepoove</groupId>
        <artifactId>poi-tl</artifactId>
        <version>1.10.0</version>
    </dependency>
</dependencies>
  1. 引入插件并且配置好修改的方式:
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.4</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <createDependencyReducedPom>true</createDependencyReducedPom>
                        <relocations>
                            <relocation>
                                <!-- 改名前 -->
                                <pattern>org.apache.poi</pattern>
                                <!-- 改名后 -->
                                <shadedPattern>shaded.org.apache.poi</shadedPattern>
                            </relocation>
                        </relocations>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

执行mvn package,如果是IDEA直接双击Lifecycle中的package就行了。

这时target目录中会有两个包,一个是original开头的原本包,因为我们没有新建类,所以这个包是空的。
另一个是和artifactId-version.jar的包,artifactIdversion是本项目创建时填写的坐标。

如图,我的这个maven项目叫rename-lib,版本是0.1:
target目录

然后把这个shaded包引入项目中使用即可,如果要使用高版本poi只需要import shaded.org.apache.poi下的类即可。


参考:


其他

排包举例,比如排除poi-tl中的poi包

<dependency>
    <groupId>com.deepoove</groupId>
    <artifactId>poi-tl</artifactId>
    <version>1.10.0</version>
    <exclusions>
        <exclusion>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
        </exclusion>
    </exclusions>
</dependency>

标签: Maven

添加新评论