如何 set/get 来自另一个 JVM 的值

How to set/get a value from another JVM

我有一个 class Normal,代码如下:

public class Normal {

    private static String myStr = "Not working...";
    private static boolean running = true;

    public static void main(String[] args) {
        while(running) {
            System.out.println(myStr);
        }
    }

}

我在另一个项目中还有一个名为 Injector 的 class。它的目的是更改 Normal 的值,即使它们不在同一个 JVM 中:

public class Injector {

    public static void main(String[] args) {
    String PID = //Gets PID, which works fine

    VirtualMachine vm = VirtualMachine.attach(PID);

    /*
    Set/Get field values for classes in vm?
    */

    }
}

我想要做的是将class Normal中的值myStrrunning分别更改为"Working!"false无需更改 Normal 中的代码(仅在 Injector 中)。

提前致谢

您需要两个 JAR:

  1. 一个是Java Agent,它使用反射来改变字段值。 Java 代理的主要 class 应该有 agentmain 入口点。

    public static void agentmain(String args, Instrumentation instr) throws Exception {
        Class normalClass = Class.forName("Normal");
        Field myStrField = normalClass.getDeclaredField("myStr");
        myStrField.setAccessible(true);
        myStrField.set(null, "Working!");
    }
    

    您必须添加 MANIFEST.MFAgent-Class 属性并将代理打包到 jar 文件中。

  1. 第二个是使用动态附加将代理 jar 注入 运行 VM 的实用程序。设 pid 为目标 Java 进程 ID。

    import com.sun.tools.attach.VirtualMachine;
    ...
    
        VirtualMachine vm = VirtualMachine.attach(pid);
        try {
            vm.loadAgent(agentJarPath, "");
        } finally {
            vm.detach();
        }
    

    the article 中有更多详细信息。