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

发布于 2024-10-28 05:45:31 字数 228 浏览 2 评论 0原文

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

简单的 *.jar 文件没问题,但是一旦加载,我想我就无法从虚拟机中卸载它们并即时替换为另一个版本。

您可以建议什么方法?

I'm writing a server application which makes use of external modules. I would like to make them to be upgradeable without requiring server restart. How do I do that? I've found OSGi but it looks very complicated and big for my task.

Simple *.jar files are ok, but once they are loaded, I suppose, I cannot unload them from VM and replace with another version on-the-fly.

What approach can you suggest?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

不醒的梦 2024-11-04 05:45:31

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

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

我建议看一下《OSGi in Action》一书,以了解这些问题并查看一些不错的示例。

It seems like OSGi is exactly what you're asking for. It can be complex, but there are ways to deal with that. Some of the complexity can be mitigated by using SpringDM or something similar to handle the boilerplate tasks of registering and consuming services in the runtime. Annotation-driven service registration and dependency injection really reduces the amount of code that needs to be written.

Another way to reduce complexity is to deploy the bulk of your application in a single bundle and only deploy the parts that need to be modular into their own bundles. This reduces your exposure to registering and using services from other bundles in the runtime as well as reducing the complexity of deployment. Code running within a bundle can use other code in the same bundle just as in a standard Java app - no need to interact with the OSGi runtime. The opposite of this approach is to break up your application into lots of discrete bundles that export well-defined services to other bundles in the system. While this is a very modular approach, it does come with extra complexity of managing all those bundles and more interaction with the OSGi runtime.

I would suggest taking a look at the book "OSGi in Action" to get a sense of the issues and to see some decent samples.

花之痕靓丽 2024-11-04 05:45:31

它至少需要您定义自定义类加载器...我不明白这怎么能比仅使用 Felix、Equinox、Knoplerfish 或任何开源 Osgi 运行时来完成任务更简单。
也许SpringDM更简单......

It would at least require you to define your custom classloader... I don't see how can this be simpler than just using Felix, Equinox, Knoplerfish or any open source Osgi runtime to do the task.
Maybe SpringDM is simpler...

陌路黄昏 2024-11-04 05:45:31

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

希望这有帮助,
内特

What you're going for is definitely possible. I believe that you can unload classes from memory by loading them in a separate ClassLoader and then disposing that ClassLoader. If you're not wanting to go all out and use OSGI, I'd recommend something like JBoss Microcontainer (http://www.jboss.org/jbossmc) or ClassWorlds (http://classworlds.codehaus.org/). It's not too terribly difficult to write something like this from scratch if your needs are specialized enough.

Hope this helps,
Nate

沩ん囻菔务 2024-11-04 05:45:31

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

If you follow the ClassLoader route (is not that difficult, really), I suggest each module to be packaged in its own jar, and use a different ClassLoader to read each jar. that way, unloading a module is the same as "discarding" the ClassLoader.

乱世争霸 2024-11-04 05:45:31

OSGi 并不那么复杂 - 将 PAX runner 与 Maven 一起使用轻而易举。

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

OSGi is not so complicated - using PAX runner with maven worked as a breeze.

Or implement your own ClassLoader and set it to JVM :
java -Djava.system.class.loader=com.test.YourClassLoader App.class

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文