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

Java中可动态加载和不可加载的应用程序模块-如何?,java,dynamic-loading,Java,Dynamic Loading,我正在编写一个利用外部模块的服务器应用程序。我想让它们可以升级而不需要重新启动服务器。我该怎么做?我发现了,但对于我的任务来说,它看起来非常复杂和庞大 简单的*.jar文件是可以的,但一旦它们被加载,我想,我就无法从VM中卸载它们,并用另一个版本动态替换它们 您可以推荐什么方法?它至少需要您定义自定义类加载器。。。我不认为这比使用Felix、Equinox、Knoplerfish或任何开源Osgi运行库来完成任务更简单。 也许SpringDM更简单…你想要的绝对是可能的。我相信,通过将类加载到单

我正在编写一个利用外部模块的服务器应用程序。我想让它们可以升级而不需要重新启动服务器。我该怎么做?我发现了,但对于我的任务来说,它看起来非常复杂和庞大

简单的*.jar文件是可以的,但一旦它们被加载,我想,我就无法从VM中卸载它们,并用另一个版本动态替换它们


您可以推荐什么方法?

它至少需要您定义自定义类加载器。。。我不认为这比使用Felix、Equinox、Knoplerfish或任何开源Osgi运行库来完成任务更简单。
也许SpringDM更简单…

你想要的绝对是可能的。我相信,通过将类加载到单独的类加载器中,然后处理该类加载器,可以从内存中卸载类。如果你不想全力以赴使用OSGI,我推荐JBossMicroContainer之类的东西(http://www.jboss.org/jbossmc)还是阶级世界(http://classworlds.codehaus.org/). 如果你的需求足够专业,那么从头开始写这样的东西并不太难

希望这有帮助,
Nate

OSGi并没有那么复杂-与maven一起使用PAX runner

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

如果您遵循
ClassLoader
路线(其实并不那么困难),我建议将每个模块打包到自己的jar中,并使用不同的ClassLoader读取每个jar。这样,卸载模块就等于“丢弃”类加载器。

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

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


我建议看一看《OSGi在行动》这本书,了解问题所在,并看看一些像样的例子。

OSGi是一个不错的选择。Spring可以简化工作,另一个选择是使用ApacheFelix/Karaf。OSGi最初是为嵌入式系统设计的,不像以前那么复杂。你能推荐一些类似helloworld的OSGi用于解决像我这样的问题的例子吗?另外,类加载器是否允许卸载类?它们可以被链接起来,这样我的类加载器只加载模块,剩下的模块留给默认模块吗?嗯,我在网上看到了OSGi部分,PAX部分看到了这里:。AFAIK类加载器不会帮助您卸载。那么@Sorontar建议的“丢弃”类加载器呢?它真的会卸载一个类吗?它应该卸载,但既然这个丢弃是由垃圾收集器完成的,所以它是不可预测的,而且相当复杂的。@binary_runner我想他说的是ClassLoader的clearAssertionStatus()方法,而不是垃圾收集器。这可以吗?非常感谢。你能为你推荐的技术推荐一些类似helloworld的教程吗?还有如何处理ClassLoader?你能推荐一些关于Java类加载器的阅读材料吗?至少其中一个有helloworld吗?我不需要任何严肃的东西,只需要可加载/不可加载的类或包;实际上,类加载/卸载不是一件简单的事情,我认为不可能有“HelloWorld”场景。Osgi是实现您所追求目标的最简单方法。不管怎样,我的2c:-)如果丢弃一个类加载器,在代码中的某个地方仍然引用该类的实例,会发生什么?或者更糟糕的是,如果加载了一个同名但版本不同的类,而仍然存在对旧实例的引用,该怎么办?它会抛出异常还是什么?这取决于。即使类加载器被丢弃,该类也不会被“卸载”,也就是说它不会是GC,直到该类的所有实例都首先被GC卸载。但是所有创建新实例的尝试都会收到一个异常。问题是它看起来太复杂了。我想要的是一些简单的方法,比如Windows中的LoadLibrary/FreeLibrary。当然不是字面意思;)