我正在编写一个使用外部模块的服务器应用程序。我想让它们无需重新启动服务器即可升级。我怎么做?我找到了OSGi,但它对于我的任务来说看起来非常复杂和庞大。
简单的 *.jar 文件是可以的,但是一旦加载它们,我想,我无法从 VM 中卸载它们并即时替换为另一个版本。
你能建议什么方法?
我正在编写一个使用外部模块的服务器应用程序。我想让它们无需重新启动服务器即可升级。我怎么做?我找到了OSGi,但它对于我的任务来说看起来非常复杂和庞大。
简单的 *.jar 文件是可以的,但是一旦加载它们,我想,我无法从 VM 中卸载它们并即时替换为另一个版本。
你能建议什么方法?
看起来 OSGi 正是您所要求的。它可能很复杂,但有一些方法可以解决这个问题。通过使用 SpringDM 或类似的东西来处理在运行时注册和使用服务的样板任务,可以减轻一些复杂性。注解驱动的服务注册和依赖注入确实减少了需要编写的代码量。
另一种降低复杂性的方法是将应用程序的大部分部署在一个包中,并且只将需要模块化的部分部署到它们自己的包中。这减少了您在运行时注册和使用来自其他包的服务的风险,并降低了部署的复杂性。在包中运行的代码可以使用同一包中的其他代码,就像在标准 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/) 之类的东西。如果您的需求足够专业,那么从头开始编写这样的东西并不太难。
希望这会有所帮助,内特
如果你按照ClassLoader
路线走(真的没那么难),我建议将每个模块打包在自己的 jar 中,并使用不同的 ClassLoader 来读取每个 jar。这样,卸载模块与“丢弃”ClassLoader 相同。
OSGi 并没有那么复杂——使用PAX runner和 maven 轻而易举。
或者实现自己的ClassLoader并将其设置为 JVM:java -Djava.system.class.loader=com.test.YourClassLoader App.class