首页 > 解决方案 > sun.tools.attach.WindowsAttachProvider 无法实例化

问题描述

我目前正在编写一个将代理附加到 JVM 进程的附加程序,并且我一直遇到这个问题。这是我的代码的简化版本:

import com.sun.tools.attach.VirtualMachine;

public class AgentAttacher {
    public static void main(String[] args) {
        try {
            String pid = "some-pid-determined-elsewhere";
            final VirtualMachine vm = VirtualMachine.attach(pid);
            vm.loadAgent("agent.jar");
            vm.detach();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行时java -jar AgentAttacher.jar,我收到以下错误:

java.util.ServiceConfigurationError: com.sun.tools.attach.spi.AttachProvider: Provider sun.tools.attach.WindowsAttachProvider could not be instantiated

我尝试tools.jarlib我的 JDK 目录添加到CLASSPATH环境变量中,包括Class-Path在 my中,并在运行 JAR 时MANIFEST.MF直接指定它。-cp我相当肯定它tools.jar正在被加载,因为它在丢失时会给出不同的错误:

Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/tools/attach/VirtualMachine

WindowsAttachProvider could not be instantiated在仅使用时也遇到了错误VirtualMachine.list(),所以我认为这与使用attach()不正确的 PID 无关。


我尝试使用以下方法加载类Class.forName()

public class AgentAttacher {
    public static void main(String[] args) {
        try {
            Class.forName("sun.tools.attach.WindowsAttachProvider");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

我得到以下堆栈跟踪:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no attach in java.library.path
        at java.lang.ClassLoader.loadLibrary(Unknown Source)
        at java.lang.Runtime.loadLibrary0(Unknown Source)
        at java.lang.System.loadLibrary(Unknown Source)
        at sun.tools.attach.WindowsAttachProvider.<clinit>(WindowsAttachProvider.java:175)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at JavaAttacker.main(JavaAttacker.java:4)

如果我不包含tools.jar在类路径中,我会在这里得到一个不同的堆栈跟踪,所以我确定它正在被加载:

java.lang.ClassNotFoundException: sun.tools.attach.WindowsAttachProvider
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at JavaAttacker.main(JavaAttacker.java:4)

我的环境是带有 JDK 和 JRE 1.8.0_212 的 VirtualBox 上的 Windows 10 Pro (1809) VM。

标签: javainstrumentationjavaagents

解决方案


看来问题在于attach.dll没有从%JAVA_HOME%\jre\bin.

将 jar 运行为:

java -Djava.library.path="%JAVA_HOME%\jre\bin" -jar AgentAttacher.jar

似乎有效,只要tools.jar在我的 jar 清单中指定Class-Path


推荐阅读