0

This question is next step in solving of attach library dynamic loading problem. I have some like this:

public static void loadAttachProvider(String binPath) throws Exception {
    /*
     * If AttachProvider is already available now then propably we are in JDK
     * or path to attach.dll was specified as java.library.path on startup
     */
    if (isAttachProviderAvailable()) return;

    /*
     * In normall-use code I have generated binPath appropriate to platform (VM)
     * family and bitness (e.g. win32 or win64)
     */
    System.setProperty("java.library.path", binPath);

    // Reload library path hack
    Field sys = ClassLoader.class.getDeclared("sys_paths");
    sys.setAccessible(true);
    sys.set(null, null);

    // Here I want to be sure that AttachProvider is available
    //System.loadLibrary("attach"); <- I'm try this too, but it's not suffiecient
    if (!isAttachProviderAvailable()) {
        throw new IOException("AttachProvider not available");
    }
}

Checking for AttachProvider availability looks like:

public static boolean isAttachProviderAvailable() {
    // This line is a substance of AttachProvider.providers() method
    ServiceLoader<AttachProvider> providers = ServiceLoader.load(AttachProvider.class, AttachProvider.class.getClassLoader());
    try {
        for (Iterator<AttachProvider> it = providers.iterator(); it.hasNext();) {
            /*
             * In normall-use code the "windows" constant is replaced
             * by something like platform-specific PLATFORM_FAMILY
             */
            if (it.next().type().equals("windows")) return true;
        }
    } catch (ServiceConfigurationError ex) {}
    return false;
}

If you run this with JDK's private JRE then all will be ok, because JDK has attach.dll in default library path.

Problem

This work great only if I remove first isAttachProviderAvailable occurence, because if I try to instantiate AttachProvider before it is available then I can't instantiate it later when attach.dll is loaded. ServiceLoader doesn't refresh according to new library path. How to solve this? How to check AttachProvider availability without instantiating or how to refresh ServiceLoader?

Community
  • 1
  • 1
kbec
  • 3,415
  • 3
  • 27
  • 42

1 Answers1

0

Solved with first attach-check replaced with something like this:

try {
    System.loadLibrary("attach");
    if (isAttachProviderAvailable()) return;
    throw new IOException("AttachProvider not available");
} catch (UnsatisfiedLinkError ex) {
   /*
    * dll can't be loaded, so we need to specify special binpath
    * and reload library path as post above
    */
}

However I'm waiting for better solution.

kbec
  • 3,415
  • 3
  • 27
  • 42