TLDR;
有什么方法可以告诉 java 卸载本机库以便我可以重新加载它?(我知道它只能在单个类加载器中加载。见下文)。我知道当类加载器被垃圾收集时它被卸载,但我没有成功强制垃圾收集。有任何想法吗?
我发现这个问题解释了为什么我会遇到错误: .dll 已经加载到另一个类加载器中?
但这并不特定于我想要做的事情。我们有一个 jar,我们希望能够在运行时动态加载(插件样式),以便在另一个服务上运行一些规模测试。
它在第一次运行时运行良好,但是当我停止测试运行并尝试卸载以前的类加载器并加载新的类加载器时,我收到以下错误:
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
这是我的方法,它创建了一个新的类加载器来动态加载我的 jar,如果之前有一个,它会通过调用使其无效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");
}
我的问题:有没有办法告诉 Java 应该卸载本机库?