【问题标题】:Java casting / classloader issuesJava 转换/类加载器问题
【发布时间】:2010-01-08 18:13:17
【问题描述】:

这是问题的简化版本:

 SomeClass c = (SomeClass) obj.getSomeClassParent()

并非总是如此,但有时会触发异常

 org.somepackage.SomeClass can't be cast to org.somepackage.SomeClass 

这怎么可能?我想这与 JAI imageio 是本机库这一事实有关,但中继这怎么可能发生?我可能错过了一些东西,但是什么?

I'm using JAI imageio version 1.1 
dcm4che 2.0.21  DICOM lib

这是原始代码

  ImageInputStream iis = ImageIO.createImageInputStream(src);
  Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM");
  ImageReader reader = iter.next();
  DicomImageReadParam param = (DicomImageReadParam) reader.getDefaultReadParam();

还有原来的例外

org.dcm4che2.imageio.plugins.dcm.DicomImageReadParam can't be cast to    
org.dcm4che2.imageio.plugins.dcm.DicomImageReadParam

Exception Image http://img215.imageshack.us/img215/3894/exception.jpg

【问题讨论】:

标签: java casting java-native-interface classloader javax.imageio


【解决方案1】:

我认为如果

  1. SomeClass 实例是从 ClassLoader X 加载的(所以它的类是 CL X 的 SomeClass 或者我们称之为:CL(X).SomeClass
  2. 但它被转换为不同的类加载器。例如。当前线程类加载器是 Y 所以SomeClass 实际上是CL(Y).SomeClass

所以你有:

  • 实例 class= CL(X).SomeClass
  • 类转换目标 = CL(Y).SomeClass

或者换句话说 - 不是同一个类 - 因此类转换异常。


可能重复:ClassCastException when casting to the same class - 它也有一些很好的建议。

【讨论】:

  • 这里基本上都有了。问题是每个实例都由不同的类加载器加载,因此每个实例上的 getClass() 将返回同一类的不同实例。您应该对此进行一些编辑,因为在两个类加载器中都加载了一个类,而不是一个实例中的一个实例和另一个中的一个类,这实际上是不可能的。
  • 确实 SomeClass 在两个类加载器中都加载了,但我提到转换是从加载到 CL X 的类的实例到加载到 CL Y 的类。我将编辑回答。
  • @Ehrann Mehdan - 更清楚,但您应该删除关于序列化的部分,这在这种情况下不适用。
  • @Robin @ Ehrann 问题肯定出在类加载器中。但是为什么我在一个应用程序中有不同的类加载器仍然是个谜。我正在寻找好的解决方案。
  • 可能不相关,但值得一看:gcc.gnu.org/bugzilla/show_bug.cgi?id=24566
【解决方案2】:

我猜你有一个问题是由于类加载器和本机库之间的不匹配。本机库被加载并与类加载器相关联,但是,程序只能真正加载本机库的一个实例。因此,如果您在类加载器 A 中加载本机库,并且它输出的类将与类加载器 A 相关联。如果您稍后在类加载器 B 中加载相同的本机库,您实际上并没有再次加载它,它仍然是为类加载器 A 传递类。因此,您要么重新部署了 webapp,要么在同一个 web 服务器中有 2 个 webapp,它们使用相同的本地库。

如果可能,您应该尝试将本机库放在 webserver 的基类路径中,这样它将由基类加载器加载,从而可供任何 webapp 使用。如果您不能这样做,并且问题只是重新部署问题,那么您可能需要取消部署并在重新部署之前稍等片刻(理论上,当与其关联的类加载器被 GCed 时,本机库将被卸载,但当然,这可能需要未知的时间)。

【讨论】:

    【解决方案3】:

    奇怪的是,您是否尝试将其转换为它扩展的对象,不确定它是否具有您需要的功能,但可能值得尝试看看它是否仍然抛出异常。

    【讨论】:

      【解决方案4】:

      从图片中我看到它看起来像一个 Web 应用程序。我读了“卡特琳娜”。所以很有可能这是一个纯粹的类加载问题。

      例如,如果您从 ImageIO 类获取的 ImageReader 由不同的类加载器加载(可能是因为它部署在不同的 webapp 中),则可能会发生这种情况,因此 getDefaultReadParam() 方法返回的 DicomImageReadParam 对象是一个实例属于 - 从技术上讲 - 不同的类别。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-23
        • 2011-12-05
        • 1970-01-01
        相关资源
        最近更新 更多