Java中的动态可加载和可卸载应用程序模块 – 如何?

我正在编写一个使用外部模块的服务器应用程序。 我想让它们可以升级,而无需重启服务器。 我怎么做? 我找到了OSGi,但它看起来非常复杂,对我的任务来说很重要。

简单的* .jar文件是可以的,但是一旦加载它们,我想,我无法从VM卸载它们并在运行中替换为另一个版本。

你能提出什么方法?

OSGi似乎正是您所要求的。 它可能很复杂,但有办法解决这个问题。 通过使用SpringDM或类似的东西来处理在运行时中注册和使用服务的样板任务,可以减轻一些复杂性。 注释驱动的服务注册和dependency injection确实减少了需要编写的代码量。

降低复杂性的另一种方法是将大部分应用程序部署在单个捆绑包中,并仅将需要模块化的部分部署到自己的捆绑包中。 这减少了您在运行时注册和使用其他捆绑服务的风险,并降低了部署的复杂性。 在捆绑包中运行的代码可以使用同一捆绑包中的其他代码,就像在标准Java应用程序中一样 – 无需与OSGi运行时交互。 与此方法相反的是将应用程序分解为许多离散捆绑包,这些捆绑包将定义良好的服务导出到系统中的其他捆绑包。 虽然这是一种非常模块化的方法,但它确实带来了管理所有这些包的额外复杂性以及与OSGi运行时的更多交互。

我建议你看看“OSGi in Action”这本书,以了解问题并看到一些不错的样本。

它至少需要你定义你的自定义类加载器…我不知道这怎么能比使用Felix,Equinox,Knoplerfish或任何开源Osgi运行时更简单来完成任务。 也许SpringDM更简单……

你想要的是绝对可能的。 我相信您可以通过将它们加载到单独的ClassLoader中然后处理该ClassLoader来从内存中卸载类。 如果您不想全力以赴并使用OSGI,我建议使用JBoss Microcontainer(http://www.jboss.org/jbossmc)或ClassWorlds(http://classworlds.codehaus.org/)。 如果您的需求足够专业,那么从头开始写这样的东西并不是非常困难。

Nate,希望这会有所帮助

如果您遵循ClassLoader路由(实际上并不困难),我建议将每个模块打包在自己的jar中,并使用不同的ClassLoader来读取每个jar。 这样,卸载模块就像“丢弃”ClassLoader一样。

OSGi并不是那么复杂 – 使用PAX跑步者和maven一样轻而易举。

或者实现自己的ClassLoader并将其设置为JVM:java -Djava.system.class.loader = com.test.YourClassLoader App.class