AttachNotSupportedException由于Attach API中缺少java_pid文件

时间:2011-04-24 09:58:14

标签: java jvmti

构建自己的探查器,我使用JVMTI API构建本机库代理。可以使用add参数-agentlib与JVM一起启动此代理程序。此外,还有Attach API,允许将代理注入正在运行的JVM。我想使用以下代码将此功能实现到我的探查器:

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.printStackTrace();
} catch (IOException e1) {
    e1.printStackTrace();
} catch (AttachNotSupportedException e) {
    e.printStackTrace();
}

它做什么?从所有可用的正在运行的虚拟机(VirtualMachine.list())中,我选择第一个虚拟机,附加到它并尝试将我的代理加载到其中。可以在UNIX系统上找到名为libagent.so的代理,但在尝试加载代理时会引发以下异常:

com.sun.tools.attach.AttachNotSupportedException:
   Unable to open socket file:
      target process not responding or HotSpot VM not loaded.

查看源代码,抛出此异常,因为它找不到名为.java_pid<pid>的文件。我没有在文档中找到有关此类文件的大量信息。我经常听说这种文件不再使用,但我正在运行Java 1.6。

我还尝试连接到其他JVM,事实上我保持这个附加过程是动态的,出于测试原因我只是尝试连接到任何JVM。


这是导致异常的代码,取自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;
   }

它说,它正在从根目录进入/proc/<pid>目录。查看JDK7的变更集,似乎他们正在对代码JDK7 Changeset to LinuxVirtualMachine

进行更改

2 个答案:

答案 0 :(得分:27)

我遇到了同样的问题。

线程中的异常&#34; main&#34; com.sun.tools.attach.AttachNotSupportedException:无法打开套接字文件:目标进程未响应或未加载HotSpot VM

解决方案被发现做了一些沉重的谷歌搜索。

第一个答案来自http://www.jvmmonitor.org/doc/index.html。出现有一个错误:

  

如果您看到其他消息&#34;无法打开套接字文件:target   进程没有响应或Hotspot VM未加载&#34;,或者你的   应用程序没有响应创建一个套接字文件,如   /tmp/.java_pid1234(例如由于挂断,文件系统权限)或   JVM Monitor无法找到创建的套接字文件(例如由于   错误7009828)。

然后经过一些搜索后,我在github上找到了另一个具有相同症状的工具的对话&#34;无法打开套接字文件&#34; (https://github.com/rhuss/jolokia/issues/34):

  

jgreen:引起:com.sun.tools.attach.AttachNotSupportedException:   无法打开套接字文件:目标进程未响应或未加载HotSpot VM

     

jgreen:对,我有它的工作,但只有当lauching与activemq完全相同的用户。   root不起作用

这最后一块是解决方案。此.attach调用成功的唯一方法是运行调用attach的java代码作为相同用户,而不是拥有运行jvm的进程的用户。就我而言,它是activemq用户。

System.out.println("HEAP: " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage());

HEAP: init = 27127296(26491K) used = 3974200(3881K) committed = 26345472(25728K) max = 675086336(659264K)

答案 1 :(得分:3)

怀疑您可能正在为正在运行的JVM 指定-Djava.io.tmpdir并且它在Java 6 Update 23或24上。如果是这种情况,您只需要升级到正在运行的实例的Update 25。

我见过这个问题的唯一参考是Jstack and Jstat stopped working with upgrade to JDK6u23。我肯定看到了更新23和jstack失败的相同问题,它在23之前工作正常并再次使用25.我还尝试了VirtualMachine.attach(pid)对23并且如果使用-Djava.io.tmpdir则失败。它适用于25。