我目前正在编写一个将代理附加到 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
我尝试将我的JDK的
tools.jar
目录中的lib
添加到CLASSPATH
环境变量中,将其包含在我的Class-Path
中的MANIFEST.MF
中,并在运行JAR时使用-cp
直接指定它.我相当确定 tools.jar
正在加载,因为它在丢失时会给出不同的错误:
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/tools/attach/VirtualMachine
我在只使用
WindowsAttachProvider could not be instantiated
时也遇到了VirtualMachine.list()
错误,所以我认为这与使用PID不正确的attach()
无关。
我试过使用
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。
看来问题出在
attach.dll
没有从%JAVA_HOME%\jre\bin
加载。
运行罐子为:
java -Djava.library.path="%JAVA_HOME%\jre\bin" -jar AgentAttacher.jar
似乎有效,只要
tools.jar
在我的罐子清单中指定Class-Path
.
在 Java 8 中,附加 API 是 JVM 默认不加载的单独 jar 的一部分。您必须将其显式包含在类路径中。通常,它位于 JDK 主目录的
\lib
文件夹中:
java -cp %JAVA_HOME%\\lib\\tools.jar -jar AgentAttacher.jar
我遇到了同样的问题,是这样解决的:
使用jdk 11构建源,找不到
tools.jar
或者tools.jar是windows
这是我的 pom.xml
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.8.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/tools.jar</systemPath>
</dependency>
# Create a local directory and put tools. jar in it
mkdir lib && cp %JAVA_8_HOME/lib/tools.jar% lib/
然后:
mvn package
java -jar attach-agent.jar