可以卸载类的唯一方法是使用的类加载器是垃圾收集。这意味着,对每个类和类加载器本身的引用都需要遵循dodo的方式。
解决问题的一个可能的解决方案是为每个JAR文件配备一个ClassLoader,为每个AppServers配置一个ClassLoader,将类的实际加载委托给特定的Jar类加载器。这样,您就可以为每个App服务器指向不同版本的JAR文件。
不过,这并不是小事一桩。OSGi平台正努力做到这一点,因为每个包都有不同的类加载器,并且依赖项由平台解决。也许一个好的解决办法就是看看它。
如果您不想使用OSGI,一种可能的实现是使用JarClassLoader为每个JAR文件初始化。
并创建一个新的多类加载器类,该类扩展了ClassLoader。这个类在内部有一个JarClassloaders的数组(或列表),在fineClass()方法中,将遍历所有内部类加载器,直到找到定义或抛出NoClassDefFoundException为止。可以提供几个访问器方法来向类中添加新的JarClassloader。对于MultiClassLoader,在网络上有几种可能的实现,因此您甚至可能不需要编写自己的实现。
如果为到服务器的每个连接实例化MultiClassLoader,原则上每个服务器都可能使用同一类的不同版本。
我在一个项目中使用了MultiClassLoader的思想,其中包含用户定义脚本的类必须从内存中加载和卸载,并且运行得很好。