打jar包时类冲突解决办法

1,409 阅读1分钟

工作中有时会遇到这样的问题:工程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,以此解决包冲突问题。