代码之家  ›  专栏  ›  技术社区  ›  Pedro d'Aquino

如何替换Java applet中加载的动态库,而不需要重新启动浏览器?

  •  1
  • Pedro d'Aquino  · 技术社区  · 17 年前

    我正在写一个自我更新的应用程序。第一次运行时,它会在客户机的计算机上安装一个本机库,这样他们就不需要每次都下载它。当它检测到安装的库的版本比新的所需的最低版本旧时,它将下载并安装新的库。

    问题是,新的库实际上没有被Java使用,直到用户关闭并重新启动浏览器(而不是标签、整个浏览器)。这是我试图避免的事情——但是,如果用户需要刷新页面,或者关闭页面并再次打开它,这是可以的。

    每次小程序启动时,我都尝试将已安装的库复制到临时文件夹中,然后总是加载该副本,但没有任何效果。这里有人做过这个吗?有什么好主意吗?操作系统是Linux、JDK 1.5、Firefox。

    谢谢!

    2 回复  |  直到 17 年前
        1
  •  1
  •   gibbss    17 年前

    这正是此Bug报告中描述的情况: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5075039 (报告称它适用于Windows,但实际上是Java问题)

    在VM终止之前,Java代码无法卸载本地DLL。一旦加载了一个DLL,它将在JVM的生命周期中一直存在,并且VM将确保它只加载一次。

    我能看到的唯一让您的场景工作的方法是,如果您能以某种方式进行版本检查和更新 之前 已加载DLL。一旦它被使用,你就被它卡住了。

        2
  •  0
  •   bdonlan    17 年前

    Java类只能通过卸载拥有它们的类加载器来卸载。由于JNI库依赖于所属的类,因此您可能需要卸载拥有该库的类的类加载器。

    尝试实例化 URLClassLoader 对于与JNI库接口的类,以及使用反射创建相关类的实例。当您想卸载它时,从一个更新的jar中创建一个新的类加载器,它引用库的新版本(使用不同的库文件名,这样您可以同时加载两个版本,直到gc处理旧版本为止)。