Java 无法实例化sun.tools.attach.WindowsAttachProvider

Java 无法实例化sun.tools.attach.WindowsAttachProvider,java,instrumentation,javaagents,Java,Instrumentation,Javaagents,我目前正在编写一个attacher,它将代理附加到JVM进程,我一直遇到这个问题。以下是我的代码的简化版本: 导入com.sun.tools.attach.VirtualMachine; 公共类代理程序{ 公共静态void main(字符串[]args){ 试一试{ String pid=“其他地方确定的某些pid”; 最终VirtualMachine vm=VirtualMachine.attach(pid); vm.loadAgent(“agent.jar”); vm.detach(); }

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

导入com.sun.tools.attach.VirtualMachine;
公共类代理程序{
公共静态void main(字符串[]args){
试一试{
String pid=“其他地方确定的某些pid”;
最终VirtualMachine vm=VirtualMachine.attach(pid);
vm.loadAgent(“agent.jar”);
vm.detach();
}捕获(例外e){
e、 printStackTrace();
}
}
}
运行
java-jar agentatcher.jar
时,出现以下错误:

java.util.ServiceConfigurationError:com.sun.tools.attach.spi.AttachProvider:Provider sun.tools.attach.WindowsAttachProvider无法实例化
我已经尝试将JDK的
lib
目录中的
tools.jar
添加到
CLASSPATH
环境变量中,包括在我的
MANIFEST.MF
中的
CLASSPATH
中,并在运行jar时使用
-cp
直接指定它。我相当确定正在加载
tools.jar
,因为它在丢失时会给出不同的错误:

线程“main”java.lang.NoClassDefFoundError中出现异常:com/sun/tools/attach/VirtualMachine 我还发现仅使用
VirtualMachine.list()
时出现
WindowsAttachProvider无法实例化的错误,因此我认为这与使用带有错误PID的
attach()
无关


我已尝试使用
class.forName()
加载该类:

公共类代理程序{
公共静态void main(字符串[]args){
试一试{
Class.forName(“sun.tools.attach.WindowsAttachProvider”);
}捕获(例外e){
e、 printStackTrace();
}
}
}
我得到以下堆栈跟踪:

线程“main”java.lang.UnsatisfiedLinkError中出现异常:java.library.path中没有附加 位于java.lang.ClassLoader.loadLibrary(未知源) 位于java.lang.Runtime.loadLibrary0(未知源) 位于java.lang.System.loadLibrary(未知源) 位于sun.tools.attach.WindowsAttachProvider。(WindowsAttachProvider.java:175) 位于java.lang.Class.forName0(本机方法) 位于java.lang.Class.forName(未知源) 位于JavaAttacker.main(JavaAttacker.java:4)
如果我没有在类路径中包含
tools.jar
,我会在这里得到一个不同的堆栈跟踪,因此我确信它正在被加载:

java.lang.ClassNotFoundException:sun.tools.attach.WindowsAttachProvider
位于java.net.URLClassLoader.findClass(未知源)
位于java.lang.ClassLoader.loadClass(未知源)
位于sun.misc.Launcher$AppClassLoader.loadClass(未知源)
位于java.lang.ClassLoader.loadClass(未知源)
位于java.lang.Class.forName0(本机方法)
位于java.lang.Class.forName(未知源)
位于JavaAttacker.main(JavaAttacker.java:4)


我的环境是一个安装了JDK和JRE 1.8.0_212的VirtualBox上的Windows 10 Pro(1809)VM。

在Java 8中,附加API是一个单独的jar的一部分,JVM默认情况下不会加载该jar。您必须在类路径中显式地包含它。通常,它位于JDK主页的
\lib
文件夹中:

java -cp %JAVA_HOME%\\lib\\tools.jar -jar AgentAttacher.jar

问题似乎是
attach.dll
没有从
%JAVA\u HOME%\jre\bin
加载

以以下方式运行jar:

java-Djava.library.path=“%java\u HOME%\jre\bin”-jar agentatcher.jar

只要在我的jar清单中的
类路径下指定了
tools.jar
,就可以正常工作。不幸的是,我已经尝试在运行jar时使用
-cp
标志包含
tools.jar
。当不包含它时,我会遇到另一个错误(找不到类),因此我相当确定它正在加载。通常,attach方法会使用一个字符串,其中提供一个整数。也许你把消息来源弄糊涂了。谢谢你指出这一点!我的实际代码使用了一个字符串,但我在这里没有正确地转录它。我更改了代码以反映这一点。您得到的异常表明无法实例化附加提供程序。你有堆栈跟踪吗?异常是通过
e.printStackTrace()
打印的,所以这是完整的堆栈跟踪,除非我遗漏了什么!请尝试
Class.forName(“sun.tools.attach.WindowsAttachProvider”)
,看看您是否获得了更好的堆栈跟踪。我已将该堆栈跟踪添加到原始问题中,谢谢!