2010-11-16 96 views
2

我正在寻找一种在运行时将类重新加载到Java中的方法。动机是使调试更高效。该应用程序是一种典型的客户端/服务器设计,可同步处理请求。为每个请求实例化一个“处理程序”对象。这是我打算动态替换的唯一课程。由于每个请求处理一个新的实例,重新加载这个类不会有任何副作用。简而言之,每当此模块发生更改时,我都不想重新启动整个应用程序。Java,运行时类重新加载

在我的设计中,Java进程意识到一个.class文件已在请求之间的类路径中更新。发生这种情况时,“处理程序”类将被卸载并加载一个新的类。

我知道我可以使用classLoader接口来加载一个新类。我似乎无法找到正确的“卸载”方式。

+1

您是否尝试过在调试器中使用热启动设施? – 2010-11-16 13:40:42

回答

3

如果没有剩余的引用,类将像其他任何对象一样被卸载和垃圾收集。这意味着不能有可达的类实例(由特定的类加载器实例加载),并且类加载器实例本身也必须符合垃圾回收的条件。

所以基本上,你所要做的就是创建一个新的类加载器实例来加载新版本的类,并确保没有引用旧版本的实例。

1

我相信你实际上需要有一个类加载器的层次结构,为了重新加载,你实际上摆脱了低级别的类加载器(通过normall GC的方式),因此它加载了所有的类。据我所知,Java EE应用服务器使用这种技术来重新加载应用程序,并且当在一个类加载器中加载的框架代码想要使用在其他地方加载的类时,有各种有趣的结果。

0

截至2015年,Java的类重新加载是一个缺失的功能。

  • 使用OSGi来创建类重新加载应用程序。
  • 使用jrebel进行测试。还有一些其他人做同样的事情。
  • 使用应用程序服务器并将要重新加载的零件外部化到单独的Web应用程序中。然后继续部署/取消部署。由于悬挂旧的ClassLoader实例,您最终会得到一些perm gen space溢出错误。
  • 使用脚本运行器来执行部分可更改代码。 JSR-223 Java脚本API支持脚本语言“Java”。

我写了一个关于类重新加载的系列。但所有这些方法都不利于生产。

恕我直言,这个类重载是凌乱的Java和它的不值得尝试的。但我非常希望这是java中的规范。