可以在Java中加载同一DLL的不同版本吗?

 2023-01-19    329  

问题描述

我有一个与一组第三方库进行交互的JNI库,并且系统上可能有一个以上版本的第三方库.对于第三方库的每个版本,出于可比性原因,我必须重新编译JNI代码.现在,我通过加载带有特定名称的DLL来处理此问题,如果版本更改,我会更改JNI接口DLL的名称,以便版本的正确名称具有正确的名称.

我希望能够根据用户想要使用的版本动态加载DLL.如果我调用system.loadlibrary在带有不同名称但相同方法签名的DLL上两次会发生什么?

可以在Java中加载同一DLL的不同版本吗?

System.loadLibrary("JNIv1");
// Same code compiled against a different third party version
System.loadLibrary("JNIv2");

我只需要一次使用一个版本,因此,如果旧版本不再可访问,这很好.

是否可以使用相同的方法签名加载两个不同版本的DLL,而无需重新启动程序?

推荐答案

这是可能的,实际上它得到了完全支持并出色地工作.

我不得不在生产环境中进行此操作,在Sun JVM上,它是坚固的.

基本上,如果您从另一个classloader加载库,则它将加载库的其他副本.那样简单.

我不建议这样做,除非您真的要…但是确实可以.

作为替代方案,取决于您的特定要求,您只能使其过于流程,并且在客户端和不同服务器之间具有简单的协议(使用JETTY/XSTREAM/HTTPCLIENT或NETTY)加载了不同的DLL版本.

本质上,这涉及您编写classloader

public class MyClassLoader extends URLClassLoader {

   protected String findLibrary(String libName) {
         if ( libName.equals("mylib.dll")) {
              return "full/path/to/library";
         }
         else {
              super.findLibrary(libName);
         }
   }
}

然后,您安排使用相关的classloader加载类的实现…

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();

    }
}

这种东西…..

其他推荐答案

我不知道Windows中DLL加载的工作方式,但是我的直觉告诉我,同时加载重叠的库绝对是不安全的.但是,也许如果您首先卸载了第一个,那可能是.

据我所知,没有办法明确卸载库.如果您查看java.lang.classloader.nativelibrary,您会发现当导致其加载的classloader加载时,将卸载库(在其finallize()方法中).因此,如果将其加载到一个单独的classloader中,然后等待收集到垃圾(带有一些邪恶的呼叫system.gc()以使其更快地实现),然后再加载新的垃圾,这可能会有所帮助.

其他推荐答案

这是不安全的,实施非常混乱.可以为DLL的不同版本具有不同的类负载器.您将必须确保收集垃圾级,以确保DLL已卸载. (请参阅 java jni> java jni> -DLL卸载)

过去,我们通过编写轻量级Java调解器进程来解决此问题,该过程处理用户的请求,并使用所请求的DLL版本创建新的Child Java流程.当用户请求不同的版本时,调解员会关闭现有的孩子,并带有不同库路径的新版本.这种方法效果很好.唯一的缺点是启动新的JVM所花费的时间,但是只有在您经常出现版本开关的请求时,这才是明显的.

.

以上所述是小编给大家介绍的可以在Java中加载同一DLL的不同版本吗?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/25884.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。