使用com.sun.tools.attach.VirtualMachine
Java API时遇到问题。我的目标应用程序(Tomcat)使用Oracle Hot Spot版本1.7.0_80运行。我试图通过来自使用Open JDK 10.0.2的另一个Java程序(在同一台机器上)的动态附加连接该tomcat。我正在使用以下代码
...............
String agentPath = Agent.class.getProtectionDomain().getCodeSource().getLocation().getPath();
agentPath = convertFileSeparators(agentPath, File.separatorChar);
String agentInstallDir = agentPath.substring(0, agentPath.lastIndexOf(File.separator));
System.out.println("My Java agent installed on the location :"+agentPath);
StringBuilder sb = new StringBuilder();
sb.append("MY_RELIC_HOME").append("=").append(agentInstallDir);
if (agentArgs != null) {
sb.append(",").append(agentArgs);
}
com.sun.tools.attach.VirtualMachine virtualMachine = com.sun.tools.attach.VirtualMachine.attach(vmID);
virtualMachine.loadAgent(agentPath, sb.toString());
.........
我能够成功地附加到目标应用程序,但是附加后在我的附加程序(运行打开的JDK 10.0.2)中出现以下异常。
com.sun.tools.attach.AgentLoadException: 0
at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:104)
at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:115)
at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachine.java:139)
at com.eg.agent.Agent.main(Agent.java:582)
第582行的代码是virtualMachine.loadAgent(agentPath, sb.toString());
。
如果我使用Java 7或8运行附加程序,则没有例外,附加成功。
为什么在使用JDK 10时发生com.sun.tools.attach.AgentLoadException: 0
异常?
答案 0 :(得分:0)
发现问题,在Java 10和8的两个版本上查看sun.tools.attach.HotSpotVirtualMachine
的源代码后,方法10和8之间的loadAgentLibrary(...)方法完全不同。
下面的代码来自1.8 ,这表明result
的值为零表示VMAttach成功。
private void loadAgentLibrary(String agentLibrary, boolean isAbsolute, String options)
throws AgentLoadException, AgentInitializationException, IOException
{
InputStream in = execute("load",
agentLibrary,
isAbsolute ? "true" : "false",
options);
try {
int result = readInt(in);
if (result != 0) {
throw new AgentInitializationException("Agent_OnAttach failed", result);
}
} finally {
in.close();
}
}
当result
的值为"return code: 0"
时,VM Attach中的以下代码来自Java 10 成功(但在1.8中,其简称为0
)
private void loadAgentLibrary(String agentLibrary, boolean isAbsolute, String options)
throws AgentLoadException, AgentInitializationException, IOException
{
String msgPrefix = "return code: ";
InputStream in = execute("load",
agentLibrary,
isAbsolute ? "true" : "false",
options);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
String result = reader.readLine();
if (result == null) {
throw new AgentLoadException("Target VM did not respond");
} else if (result.startsWith(msgPrefix)) {
int retCode = Integer.parseInt(result.substring(msgPrefix.length()));
if (retCode != 0) {
throw new AgentInitializationException("Agent_OnAttach failed", retCode);
}
} else {
throw new AgentLoadException(result);
}
}
}
在我的情况下,Java 7/8代码(目标应用程序)将result
作为0
返回到Java 10代码(VM Attach代码),这意味着VM Attach成功。应该是"return code: 0"