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

Maven项目反射调用触发的VirtualMachine类加载优先级冲突问题

Maven类加载冲突解决方案:让依赖1优先加载JDK提供的VirtualMachine类

核心原理

出现该问题的根本原因是全限定类名相同的情况下,类加载器会优先加载类路径上排序更靠前的Jar包中的类,依赖2的Jar包在类路径中的排序早于JDK的tools.jar(JDK9+对应jdk.attach模块),导致优先加载了依赖2内置的com.sun.tools.attach.VirtualMachine类。

可行方案

方案1:排除依赖2内置的attach包(优先推荐)

如果依赖2本身不需要使用它自带的com.sun.tools.attach包,直接在pom.xml中对依赖2添加排除规则即可,从根源避免冲突。

<dependency>
    <groupId>【替换为依赖2的实际groupId】</groupId>
    <artifactId>【替换为依赖2的实际artifactId】</artifactId>
    <version>【替换为依赖2的实际版本】</version>
    <exclusions>
        <exclusion>
            <groupId>【替换为依赖2中attach包的实际groupId】</groupId>
            <artifactId>【替换为依赖2中attach包的实际artifactId】</artifactId>
        </exclusion>
    </exclusions>
</dependency>

配置完成后重新打包,依赖2内置的attach包不会被引入类路径,类加载器会自动加载JDK提供的对应类。

方案2:显式声明JDK tools.jar依赖并调整排序

如果无法排除依赖2的内置attach包,可以在pom.xml中显式声明JDK的tools.jar依赖,并且将该依赖的声明位置放在依赖2之前,利用Maven依赖声明顺序优先的规则,让JDK的类优先级更高。

JDK8及更早版本配置

<!-- 该依赖必须放在依赖2的声明之前 -->
<dependency>
    <groupId>com.sun</groupId>
    <artifactId>tools</artifactId>
    <version>1.8</version>
    <scope>system</scope>
    <systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>

<!-- 依赖2的声明放在tools.jar之后 -->
<dependency>
    <groupId>依赖2的groupId</groupId>
    <artifactId>依赖2的artifactId</artifactId>
    <version>依赖2的版本</version>
</dependency>

JDK9及以上版本配置

JDK9之后tools.jar被移除,com.sun.tools.attach相关类归属到jdk.attach模块,只需要在模块描述文件module-info.java中添加模块依赖即可:

module your.project.module {
    requires jdk.attach;
}

同时保持JDK相关依赖的声明顺序早于依赖2即可。

方案3:自定义类加载器(适用于特殊场景)

如果依赖2本身必须使用它自带的com.sun.tools.attach包,无法做全局排除,可针对依赖1的ClassA所在的包自定义类加载器,打破双亲委派机制,优先加载JDK中的com.sun.tools.attach相关类,其余类依旧走正常的双亲委派逻辑。
该方案侵入性较高,仅在前两种方案无法落地时使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:27:07