5

I'm using com.sun.tools.attach from jdk's tools.jar and it need an specified java.library.path env pointing to attach.dll at startup to properly instatiate provider such as WindowsAttachProvider. For some reasons I need to dynamic loading one of bundled attach.dll. I'm try to use some like this:

public static void main(String[] args) throws Exception {
    Path bin = Paths.get(System.getProperty("user.dir"),"bin").toAbsolutePath();
    switch (System.getProperty("os.arch")) {
        case "amd64":
            bin = bin.resolve("win64");
            break;
        default:
            bin = bin.resolve("win32");
    }
    // Dynamic setting of java.library.path only seems not sufficient
    System.setProperty("java.library.path", System.getProperty("java.library.path") + File.pathSeparator + bin.toString());
    // So I try to manual loading attach.dll. This is not sufficient too.
    System.load(bin.resolve("attach.dll").toString());
    // I'm using com.sun.tools.attach in my app
    new myApp();
}

If I run this out of jdk (in normall jre) it's report to me:

java.util.ServiceConfigurationError: com.sun.tools.attach.spi.AttachProvider:
Provider sun.tools.attach.WindowsAttachProvider could not be instantiated:
java.lang.UnsatisfiedLinkError: no attach in java.library.path
Exception in thread "main" com.sun.tools.attach.AttachNotSupportedException:
no providers installed
    at com.sun.tools.attach.VirtualMachine.attach(...

How to install attach provider without specifying -Djava.library.path to point attach.dll at startup?

kbec
  • 3,415
  • 3
  • 27
  • 42
  • Did you try printing (or debugging) the paths you are forming to see if they are what you expect? – ewan.chalmers Jun 21 '12 at 08:26
  • Yes, I'm printing it before and after and they are what I expect. It seems like an attach api use this env on startup only. – kbec Jun 21 '12 at 08:32
  • 1
    You can't change java.library.path programatically by setting the system property. There are hacks using reflection. But you probably want to find another solution. – ewan.chalmers Jun 21 '12 at 08:33
  • So, how to use `attach.dll` pointed from java code? – kbec Jun 21 '12 at 08:35

1 Answers1

6

The API you are using is using loadLibrary(String). It seems you cannot successfully pre-empt (cause it to succeed) this by invoking the more explicit load(String) first.

So you must to specify the path in java.library.path.

That System property is set once early in JVM lifecycle and is not modifiable by standard means.

So the conventional solution will be to pass an appropriate java.library.path when you launch the JVM.

Alternatively, you could look into the hacks to change this property after JVM startup using reflection. I have not tried any of these.

For example, see here:

System.setProperty( "java.library.path", "/path/to/libs" );

Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );
fieldSysPath.setAccessible( true );
fieldSysPath.set( null, null );

BTW, I would recommend pre-pending your custom path to the existing path, rather than replacing it.

ewan.chalmers
  • 16,145
  • 43
  • 60
  • It's sufficient explanation of env problem, but I'm waiting for attach-api-level workaround. Thanks – kbec Jun 21 '12 at 09:47
  • Ok, I'm look into it and source of openjdk's attach. So, attach-api-level workaround is impossible regards to above. Changing sys path by reflection works and I must use it now, but I'm afraid can I trust this method in portability across Win/Mac/Lin. – kbec Jun 25 '12 at 11:33