AttachNotSupportedException due to missing java_pid file in Attach API
Building a profiler of my own, I use the JVMTI API to build a native library agent. This agent can be started together with the JVM by using the addition parameter -agentlib. In addition there is the Attach API which allows to inject an agent into a running JVM. I wanted to implement this feature to my profiler using the following code:
try {
String pid = VirtualMachine.list().get(0).id();
VirtualMachine vm = VirtualMachine.attach(pid);
vm.loadAgentLibrary("agent");
} catch (AgentLoadException e1) {
e1.printStackTrace();
} catch (AgentInitializationException e1) {
e1.printS开发者_高级运维tackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (AttachNotSupportedException e) {
e.printStackTrace();
}
What does it do? From all the available running virtual machines (VirtualMachine.list()
) I choose the first one, attach to it and try to load my agent into it. The agent, on UNIX systems named libagent.so, can be found, but when trying to load the agent the following exception is thrown:
com.sun.tools.attach.AttachNotSupportedException:
Unable to open socket file:
target process not responding or HotSpot VM not loaded.
Looking into the source code, this exception is thrown, because it cannot find a file named .java_pid<pid>
. I haven't found a lot information about this kind of file in the documentation. I often heard this kind of file is not used anymore, but I am running Java 1.6.
I also tried to attach to other JVMs, in fact I kept this attaching process dynamic, for testing reasons I just try to attach to any JVM.
This is the code which leads to the exception, taken from sun.tools.attach: LinuxVirtualMachine.java:
// Return the socket file for the given process.
// Checks working directory of process for .java_pid<pid>. If not
// found it looks in /tmp.
private String findSocketFile(int pid) {
// First check for a .java_pid<pid> file in the working directory
// of the target process
String fn = ".java_pid" + pid;
String path = "/proc/" + pid + "/cwd/" + fn;
File f = new File(path);
if (!f.exists()) {
// Not found, so try /tmp
path = "/tmp/" + fn;
f = new File(path);
if (!f.exists()) {
return null; // not found
}
}
return path;
}
It says, it is looking from root into the /proc/<pid>
directory. Looking at a changeset of the JDK7 it seems they are making changes to the code JDK7 Changeset to LinuxVirtualMachine
I experienced this same issue.
Exception in thread "main" com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded
The solution was found doing some heavy googling.
First answer came http://www.jvmmonitor.org/doc/index.html . Appears there is a bug:
If you see the additional message "Unable to open socket file: target process not responding or Hotspot VM not loaded", either your application didn't respond creating a socket file like /tmp/.java_pid1234 (e.g. due to hangup, file system permission), or JVM Monitor was not able to find the created socket file (e.g. due to the bug 7009828).
Then after some more searching I found a conversation on github for another tool which had the same symptom "Unable to open socket file" (https://github.com/rhuss/jolokia/issues/34):
jgreen: Caused by: com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded
jgreen: right I have it working but only when lauching as the exact same user as activemq. root does not work
This last piece was the solution. The only way this .attach call would be successful was through running the java code that calls attach as the same user as the one who owned the process running the jvm. In my case it was the activemq user.
System.out.println("HEAP: " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage());
HEAP: init = 27127296(26491K) used = 3974200(3881K) committed = 26345472(25728K) max = 675086336(659264K)
I suspect that you might be specifying -Djava.io.tmpdir
for your running JVM and it's on Java 6 Update 23 or 24. If that's the case you just need to upgrade to Update 25 for the running instance.
The only reference to this problem I've seen is Jstack and Jstat stopped working with upgrade to JDK6u23. I've definitely seen the same issue with Update 23 and jstack failing, where it worked fine prior to 23 and works again with 25. I also just tried VirtualMachine.attach(pid)
against 23 and it fails if -Djava.io.tmpdir
is used. It works with 25.
精彩评论