我需要不同的类加载器才能卸载类。但我需要在它们之间共享对象(实际上我得到的是ClassCastException)。那么解决这个问题的解决方案是什么?感谢
答案 0 :(得分:10)
来自不同类加载器的对象可以通过通用类加载器加载的接口和类相互交互。
答案 1 :(得分:2)
使用单独的类加载器的主要目标之一是完全防止您尝试执行的操作。安全性和名称冲突是保持这种隔离的充分理由。以下是一些可以绕过这种隔离的方法。
使用Common Class Loader
在群集中共享库
将一个应用程序的客户端JAR打包到另一个应用程序中 应用
有关详细信息,请参阅此link。
答案 2 :(得分:1)
还要提到的是,如果你正在使用接口,你可以使用java.lang.reflect.Proxy来创建一个你的类加载器本地接口的实例,它在引擎盖下用“反射”来调用“真实”(来自不同类加载器的外来对象。它很难看,如果参数或返回类型不是原始的,那么你只需要将ClassCastException传递到更远的地方。虽然你可以一些东西来完成这项工作,但一般情况下,最好是拥有一个父类加载器,其中包含一些你希望能够在类加载器中使用的共享类型,或者使用更多。 ..用于通信的序列化格式(较慢),或仅共享处理原语的接口。
答案 3 :(得分:0)
在某些情况下,通过使用具有所需类加载器的线程来“切换上下文”可能是可以接受的。例如,您通过所需的上下文创建 SingleThreadPoolExecutor 并使用该单例实例从不同的上下文执行代码。
这是我的情况:maven 多模块 Web 应用程序部署到 tomcat。一个 Web 应用程序注册了错误通知服务 bean,并为整个 JVM 注册了 DefaultUncaughtExceptionHandler
,使用 bean 通过电子邮件传递错误(内部带有附加逻辑)。当成功发送创建 bean 电子邮件的 web 应用程序抛出异常时,当不同的 web 应用程序抛出异常时,电子邮件功能无法处理 javax.mail 类(令人惊讶的是不是异常本身)。当我执行一个在执行器中发送电子邮件的方法时,两种情况都开始工作。