是否有办法可以从jvm中获取到对象并调用方法

比如我首先用java命令启动了一个程序,然后我想在另外一个java程序里,获取之前那个程序中的对象并调用相应的方法。

目前能够做到的是,可以使用jdk提供的工具包tools.jar里的方法,调用自己写的java agent

String pid = "xxxx";
HotSpotVirtualMachine vm = (HotSpotVirtualMachine) new LinuxAttachProvider().attachVirtualMachine(pid);
vm.loadAgent(".../testAgent.jar");
vm.detach();

这里的java agent可以拿到类的信息

public class TestAgent {

    public static void agentmain(String args, Instrumentation inst) throws IllegalAccessException, InstantiationException {
        System.out.println("loaded classes: " + inst.getAllLoadedClasses().length);
        System.out.println("================");
        Class[] classes = inst.getInitiatedClasses(TestAgent.class.getClassLoader());
        System.out.println("initiated classes: " + classes.length);
        for (Class clazz: classes) {
            System.out.println(clazz.getName());
        }
        System.out.println("================");
    }

}

但是似乎拿不到当前正在使用的对象或者引用。
请问有办法可以做到吗?

阅读 5.7k
3 个回答

你需要了解下 进程间通信 —— 最为一般的方式是使用 Socket(RPC)

明白一点:agentmain函数是在目标JVM进程中执行的。所以很简单,使用反射就可以调用目标JVM进程中的类的方法。

    public static void agentmain(String args, Instrumentation instrumentation)
        throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        ...
        // 反射获取目标类
        Class<?> testTarget = Class.forName("TestTarget");
        // 类实例化
        Object newInstance = testTarget.newInstance();
        // 获取目标方法
        Method end = testTarget.getDeclaredMethod("end", null);
        // 调用目标方法
        end.invoke(newInstance, null);
    }

这个平台已经快挂了么,两个回答全是高分大佬,但是都答非所问
第一个扯RPC,还说给黑盒封装,现在题主问的是怎么获取,你已经跳到有了这个功能然后封装去了
第二个完全是混分行为,获取已有对象,你这是实例化一个对象

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题