You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot应用中同名包类加载冲突的解决方案咨询

解决Spring Boot同名包类加载冲突的可行方案

方案1:Maven Shade插件重打包其中一个依赖包

既然无法修改原依赖包,可通过Maven Shade插件将其中一个jar(比如jar1)的inspector包重命名为唯一名称(如inspector.v1),再依赖重打包后的jar:

  • 在diffToolv1的pom.xml中配置Shade插件:
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.4.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <relocations>
                            <relocation>
                                <pattern>inspector</pattern>
                                <shadedPattern>inspector.v1</shadedPattern>
                            </relocation>
                        </relocations>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
  • 执行mvn package生成重打包后的jar,替换diffToolv1中原有的jar1依赖为这个重打包后的jar
  • 修改diffToolv1中所有引用inspector包的代码,改为引用inspector.v1

方案2:自定义类加载器隔离不同依赖

为diffToolv1和diffToolv2分别创建独立的类加载器,加载各自对应的jar,避免类路径冲突:

  1. 编写自定义类加载器,继承URLClassLoader,仅加载指定的jar文件:
public class CustomJarClassLoader extends URLClassLoader {
    public CustomJarClassLoader(URL[] urls, ClassLoader parent) {
        super(urls, parent);
    }

    @Override
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        // 仅加载指定包下的类,其他类委托给父类加载器
        if (name.startsWith("inspector")) {
            synchronized (getClassLoadingLock(name)) {
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    c = findClass(name);
                }
                if (resolve) {
                    resolveClass(c);
                }
                return c;
            }
        }
        return super.loadClass(name, resolve);
    }
}
  1. 在diffToolv1中,使用自定义类加载器加载jar1中的inspector类:
// 加载jar1的URL
URL jar1Url = new File("path/to/jar1.jar").toURI().toURL();
CustomJarClassLoader jar1ClassLoader = new CustomJarClassLoader(new URL[]{jar1Url}, Thread.currentThread().getContextClassLoader());
// 加载需要的类
Class<?> inspectorClass = jar1ClassLoader.loadClass("inspector.YourTargetClass");
// 通过反射创建实例并调用方法
Object instance = inspectorClass.getDeclaredConstructor().newInstance();
Method method = inspectorClass.getMethod("yourMethod");
method.invoke(instance);
  1. 同理为diffToolv2创建对应的类加载器加载jar2,确保两个模块使用各自类加载器加载同名包类

方案3:使用Spring Boot PropertiesLauncher指定类加载优先级

Spring Boot的PropertiesLauncher支持更灵活的类路径配置,可以为不同模块指定不同的jar加载顺序:

  1. 修改项目启动类的依赖,使用PropertiesLauncher:
    在Parent的pom.xml中配置:
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>com.yourpackage.ReportAnalytics</mainClass>
                <layout>ZIP</layout> <!-- 使用PropertiesLauncher需要指定ZIP布局 -->
            </configuration>
        </plugin>
    </plugins>
</build>
  1. 创建BOOT-INF/classpath.properties文件,指定diffToolv1优先加载jar1:
# 按顺序加载,jar1放在jar2前面
com.yourpackage.diffToolv1=lib/jar1.jar
com.yourpackage.diffToolv2=lib/jar2.jar
  1. 打包后启动应用,确保diffToolv1加载jar1中的inspector类

方案4:利用Java模块系统(JPMS)实现类隔离

将jar1和jar2转换为Java模块,通过模块声明实现包隔离:

  1. 为jar1添加module-info.java:
module inspector.v1 {
    exports inspector;
}
  1. 为jar2添加module-info.java:
module inspector.v2 {
    exports inspector;
}
  1. 在diffToolv1的module-info.java中声明依赖inspector.v1:
module com.yourpackage.diffToolv1 {
    requires inspector.v1;
}
  1. 在diffToolv2的module-info.java中声明依赖inspector.v2:
module com.yourpackage.diffToolv2 {
    requires inspector.v2;
}
  1. 修改Parent项目的构建配置,支持模块系统,确保不同模块依赖对应的模块

内容的提问来源于stack exchange,提问作者Pramod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 15:27:23