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

基于原生JVMTI代理实现Java虚拟机间通信的问题求助

求助:JVMTI代理附加后无法与目标VM持续通信

我正在做一个功能,想用附加的原生JVMTI代理(C++实现)让两个Java虚拟机之间能通信。核心逻辑是通过Attach API把VM A的代理附加到VM B上,之后通过这个代理把VM A的命令转发给VM B。我还做了个JavaFX应用,能调用VirtualMachine.list()列出所有运行中的Java虚拟机,每个VM对应一个按钮,点击就能给对应VM上的代理发送字符串命令。

目前已经搞定的部分

  • 成功通过Attach API把原生代理附加到运行中的VM上,Agent_OnAttach方法能正常执行,还能对目标VM B做基础的适配性检查。

卡壳的核心问题

代理成功附加之后,我没法再和它通信了。如果每次发命令都重新附加代理,会导致目标VM上挂载一堆代理(关键是还没法卸载),而且我不想用文件或者套接字这种方式来做通信。试过用JNI来实现通信,但JNI本地方法里没法复用Agent_OnAttach里初始化好的jvmtiEnv实例。目前我想到两个解决方向,但都没找到可行的实现方案:

  1. 找到能让代理执行后卸载的方法,这样每次发命令就可以重新附加;
  2. 解决JNI和代理之间的通信问题,能复用已经附加的代理实例。

附上相关代码

原生代理代码(C++)

jvmtiExtensionFunction getExtensionFunction(jvmtiEnv* jvmti, const std::string& functionName) { 
    .... 
    return function; 
} 

JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM* vm, char* options, void* reserved) { 
    jvmtiEnv* jvmti = NULL; 
    // Initialize jvmti 
    vm->GetEnv((void**) &jvmti, JVMTI_VERSION_1_2); 

    std::string isVMSuitableFunctionName("vmCheckFunction"); 
    jvmtiExtensionFunction isVMSuitableFunction = getExtensionFunction(jvmti, isVMSuitableFunctionName); 

    int result = 1; 
    if(isVMSuitableFunction != NULL) { 
        jboolean jIsVMSuitable; 
        isVMSuitableFunction(jvmti, &jIsVMSuitable); 
        if(jIsVMSuitable) { 
            result = 0; 
        } else { 
            result = 2; 
        } 
    } 
    return result; 
} 

JNIEXPORT void JNICALL Java_jni_method_tag(JNIEnv *env, jobject obj, jstring tag) { 
    // Communicate with the VM the agent has been attached to 
} 

Java类代码

public class TaggingAgent { 
    public void attachToVM(String vmID, String agentPath) throws AgentAttachException { 
        try { 
            VirtualMachine machine = VirtualMachine.attach(vmID); 
            machine.loadAgentPath(agentPath); 
            machine.detach(); 
        } catch (AgentInitializationException e) { 
            switch (e.returnValue()) { 
                case 1: 
                    throw new AgentAttachException("JVM is not suitable.", e); 
                case 2: 
                    throw new AgentAttachException("JVM doesn't support this action.", e); 
                default: 
                    throw new AgentAttachException("Couldn't attach agent to JVM.", e); 
            } 
        } catch (AttachNotSupportedException | IOException | AgentLoadException e) { 
            throw new AgentAttachException("Couldn't attach agent to JVM.", e); 
        } 
    } 

    public native void tag(String tag); 
} 

已经查过的相关问题(没找到合适方案)

  • How to communicate with jvmti agent attached on a running JVM
  • Communication between JVMTI agent and separate JVM
  • Unloading a JVMTI agent at runtime?

内容的提问来源于stack exchange,提问作者Max M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:23:25