Java 罐的动态装卸
我们有一个基于java的jersey+grizzly REST服务器,它公开了如下调用 foo.com/{game}/rules foo.com/{game}/players foo.com/{game}/matches 可以有任意数量的游戏 每个游戏都有不同的规则、玩家和比赛实现 出于历史原因,我们希望每个游戏实现使用单独的JAR 所以有REST服务器 当有类似foo.com/tentles/rules这样的电话时 我们希望REST服务器动态加载“网球”jar。jar执行其操作。然后应该卸载jar 如果下一个电话是foo.com/football/players 我们希望REST服务器动态加载“football”jar。jar执行其操作。然后应该卸载jar 有没有一种技术可以做到这一点?Java 罐的动态装卸,java,jar,classloader,dynamic-class-loaders,Java,Jar,Classloader,Dynamic Class Loaders,我们有一个基于java的jersey+grizzly REST服务器,它公开了如下调用 foo.com/{game}/rules foo.com/{game}/players foo.com/{game}/matches 可以有任意数量的游戏 每个游戏都有不同的规则、玩家和比赛实现 出于历史原因,我们希望每个游戏实现使用单独的JAR 所以有REST服务器 当有类似foo.com/tentles/rules这样的电话时 我们希望REST服务器动态加载“网球”jar。jar执行其操作。然后应该卸载j
显然,围绕这个问题有一个非常古老的问题:我不知道它在Java 8上是如何工作的,但是在Java 7中卸载一个类不仅需要卸载该类,还需要卸载其加载器,以及该类可能具有的其他对象的所有引用 卸载所有这些文件后,将调用System.gc。如果其他类仍然持有引用,那么gc将无法完成其工作 @Joop Eggen建议的OSGI是一个可行的选择。JRebel不是。代理对象 在独立类加载器中动态加载java jar文件,以避免依赖冲突并启用模块化更新。将加载[main jar folder]/lib/myLib/2.0/*.jar中的所有jar文件 代码示例 从myLib/2.0文件夹中的JAR文件创建对象:
File libDir = new File("myLib/2.0");
ProxyCallerInterface caller = ObjectBuilder.builder()
.setClassName("net.proxy.lib.test.LibClass")
.setArtifact(DirArtifact.builder()
.withClazz(ObjectBuilderTest.class)
.withVersionInfo(newVersionInfo(libDir))
.build())
.build();
String version = caller.call("getLibVersion").asString();
请参阅URLClassloader API,只需创建加载程序的新实例即可卸载jar类垃圾收集也应启用,以避免内存泄漏Java 8下自己的类加载程序可能具有更好的垃圾收集行为。每次重新启动JVM都是最好的。OSGi当然是一种固溶体。