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
?