如何 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
中的值myStr
和running
分别更改为"Working!"
和false
无需更改 Normal
中的代码(仅在 Injector
中)。
提前致谢
您需要两个 JAR:
一个是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.MF
和 Agent-Class
属性并将代理打包到 jar 文件中。
第二个是使用动态附加将代理 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 中有更多详细信息。
我有一个 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
中的值myStr
和running
分别更改为"Working!"
和false
无需更改 Normal
中的代码(仅在 Injector
中)。
提前致谢
您需要两个 JAR:
一个是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.MF
和Agent-Class
属性并将代理打包到 jar 文件中。
第二个是使用动态附加将代理 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 中有更多详细信息。