在java中卸载类? [英] Unloading classes in java?

查看:53
本文介绍了在java中卸载类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义类加载器,以便桌面应用程序可以从我需要与之交谈的 AppServer 动态开始加载类.我们这样做是因为这样做所需的罐子数量是荒谬的(如果我们想运送它们).如果我们不在运行时从 AppServer 库动态加载类,我们也会遇到版本问题.

I have a custom class loader so that a desktop application can dynamically start loading classes from an AppServer I need to talk to. We did this since the amount of jars that are required to do this are ridiculous (if we wanted to ship them). We also have version problems if we don't load the classes dynamically at run time from the AppServer library.

现在,我遇到了一个问题,我需要与两个不同的 AppServers 对话,并发现根据我首先加载的类,我可能会严重崩溃......有没有办法强制卸载类而不实际杀死JVM?

Now, I just hit a problem where I need to talk to two different AppServers and found that depending on whose classes I load first I might break badly... Is there any way to force the unloading of the class without actually killing the JVM?

希望这是有道理的

推荐答案

卸载类的唯一方法是使用的类加载器是否被垃圾回收.这意味着,对每个类的引用以及对类加载器本身的引用都需要遵循 dodo 的方式.

The only way that a Class can be unloaded is if the Classloader used is garbage collected. This means, references to every single class and to the classloader itself need to go the way of the dodo.

您的问题的一种可能解决方案是为每个 jar 文件使用一个类加载器,并为每个 AppServer 使用一个类加载器,将类的实际加载委托给特定的 Jar 类加载器.这样,您就可以为每个应用服务器指向不同版本的 jar 文件.

One possible solution to your problem is to have a Classloader for every jar file, and a Classloader for each of the AppServers that delegates the actual loading of classes to specific Jar classloaders. That way, you can point to different versions of the jar file for every App server.

不过,这并非微不足道.OSGi 平台致力于做到这一点,因为每个包都有一个不同的类加载器,并且依赖关系由平台解决.也许一个好的解决方案是看一看.

This is not trivial, though. The OSGi platform strives to do just this, as each bundle has a different classloader and dependencies are resolved by the platform. Maybe a good solution would be to take a look at it.

如果您不想使用 OSGI,一种可能的实现可能是使用 JarClassloader 类用于每个 JAR 文件.

If you don't want to use OSGI, one possible implementation could be to use one instance of JarClassloader class for every JAR file.

并创建一个新的 MultiClassloader 类来扩展 Classloader.这个类在内部会有一个 JarClassloader 的数组(或 List),并且在 defineClass() 方法中将遍历所有内部类加载器,直到可以找到定义,或者抛出 NoClassDefFoundException.可以提供几个访问器方法来向类添加新的 JarClassloader.网络上有多种可能的 MultiClassLoader 实现,因此您甚至可能不需要自己编写.

And create a new, MultiClassloader class that extends Classloader. This class internally would have an array (or List) of JarClassloaders, and in the defineClass() method would iterate through all the internal classloaders until a definition can be found, or a NoClassDefFoundException is thrown. A couple of accessor methods can be provided to add new JarClassloaders to the class. There is several possible implementations on the net for a MultiClassLoader, so you might not even need to write your own.

如果您为每个到服务器的连接实例化一个 MultiClassloader,原则上每个服务器都可能使用同一类的不同版本.

If you instanciate a MultiClassloader for every connection to the server, in principle it is possible that every server uses a different version of the same class.

我在一个项目中使用了 MultiClassloader 的想法,其中包含用户定义脚本的类必须从内存中加载和卸载,而且效果很好.

I've used the MultiClassloader idea in a project, where classes that contained user-defined scripts had to be loaded and unloaded from memory and it worked quite well.

这篇关于在java中卸载类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆