我正在编写一个使用外部模块的服务器应用程序。我想让它们升级而不需要重启服务器。我怎么做?我找到了OSGi,但它看起来非常复杂,对我的任务来说很重要。
简单* .jar文件没问题,但是一旦加载它们,我想,我无法从VM中卸载它们并在运行中替换为另一个版本。
你能提出什么方法?
答案 0 :(得分:4)
似乎OSGi正是您所要求的。它可能很复杂,但有办法解决这个问题。通过使用SpringDM或类似的东西来处理在运行时中注册和使用服务的样板任务,可以减轻一些复杂性。注释驱动的服务注册和依赖注入确实减少了需要编写的代码量。
降低复杂性的另一种方法是将大部分应用程序部署在一个捆绑包中,并仅将需要模块化的部分部署到自己的捆绑包中。这减少了您在运行时注册和使用其他捆绑服务的风险,并降低了部署的复杂性。在捆绑包中运行的代码可以使用同一捆绑包中的其他代码,就像在标准Java应用程序中一样 - 无需与OSGi运行时交互。与此方法相反的是将应用程序分解为许多离散捆绑包,这些捆绑包将定义良好的服务导出到系统中的其他捆绑包。虽然这是一种非常模块化的方法,但它确实带来了管理所有这些包的额外复杂性以及与OSGi运行时的更多交互。
我建议你看看“OSGi in Action”这本书,以了解问题并看到一些不错的样本。
答案 1 :(得分:2)
至少需要你定义你的自定义类加载器...我不知道这怎么能比使用Felix,Equinox,Knoplerfish或任何开源Osgi运行时更简单。 也许SpringDM更简单...
答案 2 :(得分:1)
你想要的是绝对可能的。我相信您可以通过将它们加载到单独的ClassLoader中然后处理该ClassLoader来从内存中卸载类。如果您不想全力以赴并使用OSGI,我建议使用JBoss Microcontainer(http://www.jboss.org/jbossmc)或ClassWorlds(http://classworlds.codehaus.org/)。如果您的需求足够专业,那么从头开始写这样的东西并不是非常困难。
希望这有帮助, 内特
答案 3 :(得分:1)
如果您遵循ClassLoader
路线(确实不是那么困难),我建议将每个模块打包在自己的jar中,并使用不同的ClassLoader来读取每个jar。这样,卸载模块与“丢弃”ClassLoader相同。
答案 4 :(得分:0)
OSGi并不是那么复杂 - 使用 PAX runner 与maven一起工作轻而易举。
或者实现自己的 ClassLoader 并将其设置为JVM: java -Djava.system.class.loader = com.test.YourClassLoader App.class