工作中有时会遇到这样的问题:工程A依赖了B1(B版本为1,简记为B1),另一个工程C依赖了A和B2,由于B1和B2不兼容导致出现依赖冲突: 如果B2相对B1中新增了类ClassB,可能会导致ClassNotFoundException; 如果B2相对B1删除了某个方法,可能导致NoSuchMethodError。
解决办法:常见解决办法是统一依赖版本,统一用B1或B2版本,但实际情况有时并不允许这么做,可能A必须依赖B1,C必须依赖B2,这种情况可以通过maven-shade-plugin的relocation来解决。
maven-shade-plugin是一个maven打包工具,可以配置relocation来将A中对B1的依赖的类路径进行覆盖,例如:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<!-- Run shade goal on package phase -->
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>org.slf4j:*</exclude>
<exclude>log4j:*</exclude>
</excludes>
</artifactSet>
<relocations>
<relocation>
<pattern>okhttp3</pattern>
<shadedPattern>shade.okhttp3</shadedPattern>
</relocation>
<relocation>
<pattern>com.google</pattern>
<shadedPattern>shade.com.google</shadedPattern>
</relocation>
</relocations>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.netease.kaola.mirana.AggregateJob</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
示例中将okhttp3路径下的类全部重命名为shade.okhttp3,com.google路径下的类全部重命名为shade.com.google,以此解决包冲突问题。