基于原生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实例。目前我想到两个解决方向,但都没找到可行的实现方案:
- 找到能让代理执行后卸载的方法,这样每次发命令就可以重新附加;
- 解决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.
相关产品推荐
相关产品推荐

