Search code examples
javainstrumentationjavaagents

sun.tools.attach.WindowsAttachProvider could not be instantiated


I'm currently writing an attacher which attaches agents to JVM processes, and I keep running into this issue. Here's a simplified version of my code:

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

When running java -jar AgentAttacher.jar, I get the following error:

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

I have tried adding tools.jar from the lib directory of my JDK to the CLASSPATH environment variable, including it in the Class-Path in my MANIFEST.MF, and directly specifying it using -cp while running the JAR. I'm fairly certain that tools.jar is being loaded because it gives a different error when missing:

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

I'm also getting the WindowsAttachProvider could not be instantiated error while only using VirtualMachine.list(), so I don't think this is related to using attach() with an incorrect PID.


I've tried loading the class using Class.forName():

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

and I get the following stack trace:

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)

If I don't include tools.jar in the classpath, I get a different stack trace here, so I'm sure it's being loaded:

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)

My environment is a Windows 10 Pro (1809) VM on VirtualBox with JDK & JRE 1.8.0_212.


Solution

  • It appears that the issue was with attach.dll not loading from %JAVA_HOME%\jre\bin.

    Running the jar as:

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

    appears to have worked, so long as tools.jar is specified in my jar manifest under Class-Path.