我有一个 JNI 库,它与一组第三方库交互,并且系统上可能有多个版本的第三方库。对于每个版本的第三方库,出于可比性的原因,我都必须重新编译 JNI 代码。现在,我通过加载具有特定名称的 DLL 来处理此问题,如果版本发生更改,我会更改 JNI 接口 DLL 的名称,以便该版本的正确名称具有正确的名称来加载。
我希望能够根据用户想要使用的版本动态加载 dll。如果我对名称不同但方法签名相同的 DLL 调用 System.loadLibrary 两次,会发生什么情况?
System.loadLibrary("JNIv1");
// Same code compiled against a different third party version
System.loadLibrary("JNIv2");
我一次只需要使用其中一个版本,因此如果旧版本不再可用也没关系。
是否可以在不重新启动程序的情况下加载具有相同方法签名的两个不同版本的 DLL?
这是可能的,事实上它得到了完全的支持并且工作得非常出色。
我必须在生产环境中执行此操作,并且在 sun JVM 上它坚如磐石。
基本上,如果您从不同的类加载器加载库,那么它将加载该库的不同副本。就这么简单。
我不建议这样做,除非你真的必须这样做......但它确实有效。
作为替代方案,根据您的具体要求,您可以将其从进程中删除,并在客户端和不同服务器之间使用一个简单的协议(例如使用 jetty/xstream/httpclient 或 netty),每个服务器都有不同的协议已加载 dll 版本。
本质上,这涉及到你编写一个类加载器
public class MyClassLoader extends URLClassLoader {
protected String findLibrary(String libName) {
if ( libName.equals("mylib.dll")) {
return "full/path/to/library";
}
else {
super.findLibrary(libName);
}
}
}
然后您安排使用相关的类加载器加载类的实现...
public interface Implementation {
}
public class ImplementationLookerUpper {
Classloader v1 = new MyClassloader(version1);
Classloader v2 = new MyClassloader(version2);
public Implementation implementationUsingVersion(Version someversion) {
Classloader classloader = pickCorrectClassLoaderForVersion(someVersion);
return (Implementation) classloader.loadClass(RealImplementation.class.getName()).newInstance();
}
}
那种事......
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)