Java 由于类加载器问题导致的ClassCastException的解决方案

Java 由于类加载器问题导致的ClassCastException的解决方案,java,classloader,classcastexception,Java,Classloader,Classcastexception,我有两个类装入器,它们装入同一个类。所以,很明显,这些不能相互转换。但是我需要访问在另一个类加载器中创建的对象 我可以访问这两个类加载器。如何在其他类中使用该对象?我不需要强制转换对象来匹配当前的类加载器 但问题是返回的对象的类型是object。所以,我必须放下这个对象来访问一些方法。我该怎么做?像下面这样的普通类型转换会导致ClassCastException,我已经知道了 Mojo mojo = (Mojo) descriptor.getMojo(); descriptor#getMojo

我有两个类装入器,它们装入同一个类。所以,很明显,这些不能相互转换。但是我需要访问在另一个类加载器中创建的对象

我可以访问这两个类加载器。如何在其他类中使用该对象?我不需要强制转换对象来匹配当前的类加载器

但问题是返回的对象的类型是
object
。所以,我必须放下这个对象来访问一些方法。我该怎么做?像下面这样的普通类型转换会导致ClassCastException,我已经知道了

Mojo mojo = (Mojo) descriptor.getMojo();
descriptor#getMojo()
返回类型为
Mojo
的对象,但方法返回
object
。你怎么能做到这一点

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


我已经阅读了所有关于类加载的理论,但是没有一个专门针对这一点指定合适的解决方案。

为什么有两个cloassloader,它们加载相同的类?这可能是一个程序问题。听起来好像您正在某个地方缓存类加载器,并以错误的方式重新使用它们。如果不是这样,请尝试多类加载程序

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

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);
}

最简单的方法是使用反射。这允许您在“正常”代码中对任何可以对其进行修改的内容进行修改

AFAIK,不,您不能将一个类装入器装入的类的对象强制转换为另一个类装入器

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

    • 反射没有那么糟糕,在这里是合适的。
      顺便说一句,这是一个Maven插件吗

      您将需要以下内容:

      Mojo mojo = (Mojo)descriptor.getClass().getMethod("getMojo").invoke(descriptor);
      
      我遗漏了很多——特别是异常处理——但这应该会引导您找到所需的Javadoc。这很好,但请仔细阅读


      如果你也有两个魔咒课程,演员阵容将会中断,你将不得不做更多的反思来做任何你需要用邪恶孪生魔咒做的事情

      我认为存储字节数组而不是对象是更好的选择。反序列化时,获取字节数组并转换为对象

      我也遇到了同样的问题,字节数组方法也起了作用

      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(<<read byte[] where you stored earlier>>);
          ObjectInput in = null;
      
          try {
              in = new ObjectInputStream(bis);
              <Your Class >cachedRes = ( Your Class) in.readObject();
          } catch (IOException e) {
              e.printStackTrace();
          } catch (ClassNotFoundException e) {
              e.printStackTrace();
          }
      
      ByteArrayInputStream bis=new ByteArrayInputStream();
      ObjectInput in=null;
      试一试{
      in=新的ObjectInputStream(bis);
      cachedRes=(您的类)在.readObject()中;
      }捕获(IOE异常){
      e、 printStackTrace();
      }catch(classnotfounde异常){
      e、 printStackTrace();
      }
      
      在您的实例中,如果这样做会发生什么:
      objecto=descriptor.getMojo();System.out.println(o.getClass)使用两个不同的类加载器?这里最重要的问题是:您在这里实际想要实现什么?这是一个学术练习还是有一个真实的用例支持这种情况?@Bringer128它返回相同的类名package.Mojo。我在想是否有可能通过getClass()和#cast(Object o)方法执行上述转换?@Sanjay T.Sharma绝对没有。我正在修复一个现有的代码。@ravana你看到了吗?很遗憾,我没有能力更改类加载器。我可以访问这两个,但我不能创建类似MultipleClassloader的东西!getClass()方法是否返回同时包含该类及其类加载器的类?如果是这样的话,有没有一种方法可以使用这样的机制来实现这一点?我一直在研究这个解决方案。我可以用另一种方式。我想知道更多的细节。比如说,我已经通过findClass方法获得了类对象。那我该怎么办?如前所述,我需要将我的对象强制转换到这个返回的类。Mojo=class.cast(object)给了我编译器错误,因为它认为类#cast返回object类型的对象。你可以像平常一样用一个类加载器来实现你的代码。multiclassloader只处理multilpe类加载器,仅此而已。我明白了。给定的代码使用反射。但我对反思的了解非常有限。你能为答案添加一个简单的解决方案吗?那会很有帮助的!使用反射时没有简单的解决方案。这是非常乏味的:(我不想从一个类加载器转换到另一个类加载器。但这就是我在执行上述转换时发生的情况。我如何通过在同一个类加载器?(Mojo)描述符中进行转换。getMojo()不起作用!这是因为“Mojo”描述符中的实例是由不同的类加载器加载的,而不是您试图在其中检索它的类加载器。我需要更多的上下文。这是什么类型的应用程序?Web应用程序?这里涉及多个线程吗?它是一个java应用程序,在单个线程上运行。使用classworlds 1.1进行类加载。它确实是一个maven插件。我不会请仔细阅读并让您知道它是如何运行的。您指的是什么javadoc?相关的类和方法javadoc。