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

Java虚拟机Attach API:加载Agent前检查是否已加载

如何避免重复加载Java Attach Agent?

问题场景

现有代码通过Java Attach API加载自定义Agent,但无法判断目标VM是否已加载该Agent,尝试调用getSystemProperties()和getAgentProperties()均未获取到Agent相关信息,需要实现重复加载的规避逻辑。

用户原代码:

import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import java.util.List;

public class ListVM{
  public static void main(String[] args){
        List<VirtualMachineDescriptor> vmList = VirtualMachine.list();
        for(VirtualMachineDescriptor vm : vmList){
        System.out.println("name: " + vm.displayName() + " id :" + vm.id());
        try{
            VirtualMachine vm0 = VirtualMachine.attach(vm.id());
            // load agent, agent class's agentmain will be invoked. 
            vm0.loadAgent("/root/tmp/ChinaAgent.jar");
            System.out.println("Load agent done.");
            vm0.detach();
        }catch(Exception e) {
            System.out.println("exception : " + e.getMessage());
        }
        }
  }
}

解决方案

Java Attach API本身没有提供直接查询自定义Agent是否已加载的方法,可通过以下两种方式实现:

方法1:在Agent中添加自定义系统属性标记(推荐)

这是最可靠的主动检查方式,步骤如下:

  1. 修改你的Agent类,在agentmain方法中设置唯一的系统属性作为已加载标记:
public class ChinaAgent {
    public static void agentmain(String args, Instrumentation inst) {
        // 添加自定义标记,确保键名唯一,避免冲突
        System.setProperty("china.agent.loaded", "true");
        // 你的Agent业务逻辑...
    }
}
  1. 在Attach代码中,通过getSystemProperties()检查该标记:
VirtualMachine vm0 = VirtualMachine.attach(vm.id());
try {
    // 检查Agent是否已加载
    String agentLoadedFlag = vm0.getSystemProperties().getProperty("china.agent.loaded");
    if (!"true".equals(agentLoadedFlag)) {
        vm0.loadAgent("/root/tmp/ChinaAgent.jar");
        System.out.println("Load agent done.");
    } else {
        System.out.println("Agent already loaded on VM " + vm.id());
    }
} catch (Exception e) {
    System.out.println("exception : " + e.getMessage());
} finally {
    vm0.detach();
}

方法2:捕获重复加载的异常

当重复调用loadAgent()加载同一个Agent时,目标VM会抛出AgentLoadException或AgentInitializationException,可通过捕获这些特定异常判断:

VirtualMachine vm0 = VirtualMachine.attach(vm.id());
try {
    vm0.loadAgent("/root/tmp/ChinaAgent.jar");
    System.out.println("Load agent done.");
} catch (AgentLoadException e) {
    // 重复加载时通常会抛出此异常
    System.out.println("Agent already loaded on VM " + vm.id());
} catch (Exception e) {
    System.out.println("exception : " + e.getMessage());
} finally {
    vm0.detach();
}

这种方式无需修改Agent,但属于被动判断,异常信息可能因JDK版本略有差异。

关于getAgentProperties()的说明

getAgentProperties()返回的是JDK自带的Attach Agent(tools.jar中的实现)的属性,并非自定义Agent的属性,因此无法通过它查询自定义Agent的加载状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 10:29:55