Java转换/类加载器问题

以下是问题的简化版本:

SomeClass c = (SomeClass) obj.getSomeClassParent() 

并非总是如此,有时会触发exception

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

这怎么可能 ? 我想它与JAI imageio是本机lib这一事实有关,但是中继怎么会发生这种情况呢? 我可能错过了什么,但是什么?

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

这是原始代码

  ImageInputStream iis = ImageIO.createImageInputStream(src); Iterator 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图像http://img215.imageshack.us/img215/3894/exception.jpg

我想如果发生这种情况会发生

  1. 一个SomeClass实例是从ClassLoader X加载的(所以它的类是CL X的SomeClass或让我们调用它: CL(X).SomeClass
  2. 但它正在使用不同的类加载器。 例如,当前的Threads类加载器是Y所以SomeClass实际上是CL(Y).SomeClass

所以你有了:

  • instance class = CL(X).SomeClass
  • class cast target = CL(Y).SomeClass

或者换句话说 – 不是同一个类 – 因此类强制转换exception。


在转换为同一个类时可能重复: ClassCastException – 它也有一些很好的建议。

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

如果可能,您应该尝试将本机库放在Web服务器的基类路径中,以便它将由基类加载器加载,因此可以被任何webapp使用。 如果你不能这样做,并且问题只是一个重新部署问题,那么你可能想要在重新部署之前取消部署并稍等一下(理论上,当与它相关联的类加载器被GCs时,本机lib将被卸载,但当然,这可能需要一段时间)。

奇怪你有没有尝试将它转换为它扩展的对象,不确定它是否具有你需要的function但可能值得尝试看看它是否仍然抛出exception。

从图像中我看到它看起来像一个Web应用程序。 我读’catalina’。 所以有一个很大的机会,它是一个纯粹的类加载问题。

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