由于ClassLoader问题导致ClassCastException的解决方案

我有两个ClassLoader加载相同的类。 所以,显然这些不能相互投射。 但是我需要访问在另一个ClassLoader中创建的对象。

我可以访问两个ClassLoader。 如何在其他类中使用该对象? 我不需要将对象转换为与当前ClassLoader匹配。

但问题是返回的对象的类型是Object 。 所以,我必须抛弃该对象来访问某些方法。 我怎样才能做到这一点? 像下面这样的正常转换会导致ClassCastException,我已经知道了。

 Mojo mojo = (Mojo) descriptor.getMojo(); 

descriptor#getMojo()返回Mojo类型的对象,但该方法返回Object 。 怎么办呢?

如果您需要更多信息,请告诉我。

我已经阅读了关于类加载的所有理论,但没有一个为此指定了适当的解决方案。

AFAIK,不,你不能在另一个类加载器中转换由一个类加载器加载的类的对象。

  • 一种解决方案是创建一个“通用”类加载器,它加载要由自定义类加载器使用的类。 因此,在您的情况下,您将有一个新的类加载器,它将加载给定的类,您的自定义类加载器将扩展此类加载器。
  • 另一种解决方案是在两个类加载器之间传递“序列化”状态。 将一个实例序列化为字节数组,并通过反序列化对象流来重构另一个类加载器中的对象。

反思并不是那么糟糕,在这里是恰当的。
这是一个Maven插件,BTW?

你会想要这样的东西:

 Mojo mojo = (Mojo)descriptor.getClass().getMethod("getMojo").invoke(descriptor); 

我遗漏了很多 – 特别是exception处理 – 但这应该会引导你到你需要的Javadoc。 这很好,但请仔细阅读。

如果你还有两个Mojo课程,那么演员阵容将会破裂,你必须做更多的反思来做你需要做的任何与邪恶的双胞胎Mojo。

为什么你有2个CloassLoader,它们加载同一个类? 这可能是一个编程问题。 听起来你正在某个地方缓存ClassLoader并以错误的方式重用它们。 如果不是这种情况,请尝试使用MultiClassLoader。

创建一个包含多个其他类加载器的MultiClassLoader。 您可以使用这些MultiClassLoader加载所需的所有类。 但是你必须在一开始就创建这些MultiClassLoader,而不是在加载类时。

 public class MultiClassLoader extends ClassLoader 

你将拥有一个类加载器的集合,并在findClass(…)中迭代所有这些注册的加载器。

 protected Class findClass(String aName) throws ClassNotFoundException { for (Iterator iter = multiLoaders.iterator(); iter.hasNext();) { ClassLoader tmpLoader = (ClassLoader)iter.next(); try { return tmpLoader.loadClass(aName); } catch (ClassNotFoundException e) { } } throw new ClassNotFoundException(aName); } 

最简单的方法是使用reflection。 这允许你在“普通”代码中搜索任何你能做的事情。

我认为更好的选择只是存储字节数组而不是对象。 在deserliazing,获取字节数组并转换为对象。

我有相同的问题和字节数组方法工作。

 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutput out = null; try { out = new ObjectOutputStream(bos); out.writeObject(cachedValue); byte b[] = bos.toByteArray(); //Store in DB, file wherever here using b[]. I am not writing code to store it as it may vary in your requirement. } catch (IOException e) { e.printStackTrace(); } 

从字节数组中读取:

 ByteArrayInputStream bis = new ByteArrayInputStream(<>); ObjectInput in = null; try { in = new ObjectInputStream(bis); cachedRes = ( Your Class) in.readObject(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }