【问题标题】:AttachNotSupportedException due to missing java_pid file in Attach APIAttachNotSupportedException 由于 Attach API 中缺少 java_pid 文件
【发布时间】:2011-08-11 19:26:21
【问题描述】:

构建我自己的分析器,我使用JVMTI API 来构建本机库代理。通过使用附加参数 -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()) 中,我选择第一个,附加到它并尝试将我的代理加载到其中。可以找到名为 libagent.so 的 UNIX 系统上的代理,但在尝试加载代理时会引发以下异常:

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/&lt;pid&gt; 目录。查看 JDK7 的变更集,他们似乎正在更改代码 JDK7 Changeset to LinuxVirtualMachine

【问题讨论】:

    标签: java jvmti


    【解决方案1】:

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

    我见过的唯一提到这个问题的是Jstack and Jstat stopped working with upgrade to JDK6u23。我肯定已经看到更新 23 和 jstack 失败的相同问题,它在 23 之前运行良好,并且在 25 之前再次运行。我也刚刚尝试 VirtualMachine.attach(pid) 对抗 23,如果使用 -Djava.io.tmpdir,它会失败。它适用于 25。

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题。

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

      通过一些繁重的谷歌搜索找到了解决方案。

      第一个答案是 http://www.jvmmonitor.org/doc/index.html 。看来有bug:

      如果您看到附加消息“无法打开套接字文件:目标 进程无响应或 Hotspot VM 未加载”,您的 应用程序没有响应创建一个套接字文件,如 /tmp/.java_pid1234(例如由于挂断、文件系统权限),或 JVM Monitor 无法找到创建的套接字文件(例如,由于 错误 7009828)。

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

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

      jgreen:是的,我有它的工作,但只有在作为与 activemq 完全相同的用户启动时。 根不工作

      最后一块是解决方案。这个 .attach 调用成功的唯一方法是通过运行调用 attach 的 java 代码,以 same 用户作为拥有运行 jvm 的进程的用户。在我的例子中,它是 activemq 用户。

      System.out.println("HEAP: " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage());
      
      HEAP: init = 27127296(26491K) used = 3974200(3881K) committed = 26345472(25728K) max = 675086336(659264K)
      

      【讨论】:

      • 与同一用户合作!非常感谢!
      • 我以 root 身份使用但低于错误。错误:不支持附加:无法打开套接字文件:目标进程未响应或未加载 HotSpot VM com.sun.tools.attach.AttachNotSupportedException:无法打开套接字文件:目标进程未响应或未加载 HotSpot VM
      • @RanjeetRanjan,该解决方案在以拥有该进程的同一用户身份运行时有效。最后一个注释块指出,如果进程不属于 root,即使你是 root 也不会工作。
      • 你能帮我找到用户吗?
      • 最后我通过执行 sudo -u tomcat bin/jpenable 获得了成功。非常感谢。
      猜你喜欢
      • 2018-07-25
      • 2013-07-01
      • 2021-10-05
      • 2013-01-08
      • 1970-01-01
      • 1970-01-01
      • 2017-03-30
      • 2012-06-20
      • 1970-01-01
      相关资源
      最近更新 更多