TLDR;
Is there any way to tell java to UN-load a native library so that I can re-load it? (I understand it can only be loaded in a single class loader. See below). I know it's unloaded when the classloader is garbage collected, but I've had no success forcing a garbage collection. Any ideas?
I found this question that explains why I'm hitting my error: .dll already loaded in another classloader?
But it's not specific to what I'm wanting to do. We have a jar that we want to be able to dynamically load at runtime (plugin style) to run some scale tests on another service.
It works fine on the first run, but when I stop the test run and attempt to unload the previous classloader and load a new one, I get the following error:
Caused by: java.lang.UnsatisfiedLinkError: Could not load J2V8 library. Reasons:
no j2v8_macosx_x86_64 in java.library.path
Native Library /Users/brian.trezise/libj2v8_macosx_x86_64.dylib already loaded in another classloader
at com.eclipsesource.v8.LibraryLoader.loadLibrary(LibraryLoader.java:71)
at com.eclipsesource.v8.V8.load(V8.java:70)
at com.eclipsesource.v8.V8.createV8Runtime(V8.java:132)
... 8 more
Here's my method, which creates a new classloader to dynamically load my jar, and if one was previously it invalidates it by calling classLoader.close()
:
public void reloadJar(String jarName) throws IOException {
if (this.classLoader != null) {
classLoader.close(); //Invalidate the old class loader so we can load a new one
}
File file = new File(JAR_FILE_DIR + jarName);
if (!file.exists()) {
throw new IllegalStateException("The specified file does not exist");
}
URL urls[] = {file.toURI().toURL()};
classLoader = new EmbeddedJarClassLoader(urls, Thread.currentThread().getContextClassLoader());
LOGGER.info("Finished loading scale test jar");
}
My question: Is there any way to tell Java that a native library should be unloaded?