java 由于附加 API 中缺少 java_pid 文件,AttachNotSupportedException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5769877/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 12:41:48  来源:igfitidea点击:

AttachNotSupportedException due to missing java_pid file in Attach API

javajvmti

提问by Konrad Reiche

Building a profiler of my own, I use the JVMTIAPI 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 AttachAPI which allows to inject an agent into a running JVM. I wanted to implement this feature to my profiler using the following code:

构建我自己的分析器,我使用JVMTIAPI 构建本地库代理。该代理可以通过使用附加参数 -agentlib 与 JVM 一起启动。此外,还有允许将代理注入正在运行的 JVM 中的附加API。我想使用以下代码在我的分析器中实现此功能:

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();
}

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:

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

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.

查看源代码,抛出了这个异常,因为它找不到名为.java_pid<pid>. 我在文档中没有找到很多关于这种文件的信息。我经常听说这种文件不再使用了,但我正在运行 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.

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



This is the code which leads to the exception, taken from sun.tools.attach: LinuxVirtualMachine.java:

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

它说,它正在从根/proc/<pid>目录中查看。查看 JDK7 的变更集,似乎他们正在将代码JDK7 Changeset更改为 LinuxVirtualMachine

回答by kwoodson

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

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

The solution was found doing some heavy googling.

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

First answer came http://www.jvmmonitor.org/doc/index.html. Appears there is a bug:

第一个答案是http://www.jvmmonitor.org/doc/index.html。出现了一个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).

如果您看到附加消息“无法打开套接字文件:目标进程未响应或未加载热点虚拟机”,则说明您的应用程序没有响应创建 /tmp/.java_pid1234 之类的套接字文件(例如,由于挂断、文件系统权限),或者 JVM Monitor 无法找到创建的套接字文件(例如,由于错误 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):

然后经过更多搜索,我在 github 上找到了另一个工具的对话,该工具具有相同的症状“无法打开套接字文件”(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

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

jgreen:是的,我让它工作,但只有在以与 activemq 完全相同的用户身份启动时才有效。根不起作用

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 sameuser as the one who owned the process running the jvm. In my case it was the activemq user.

最后一块是解决方案。这个 .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)

回答by WhiteFang34

I suspectthat you might be specifying -Djava.io.tmpdirfor your running JVM andit'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.

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

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.tmpdiris used. It works with 25.

我所看到的对这个问题的唯一参考是Jstack 和 Jstat 停止工作升级到 JDK6u23。我肯定在更新 23 和 jstack 失败时看到了同样的问题,它在 23 之前运行良好,并在 25 上再次运行。我也只是尝试过VirtualMachine.attach(pid)23,如果-Djava.io.tmpdir使用它就会失败。它适用于 25。