Java 转换/类加载器问题
这是问题的简化版本:
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
Here is the simplified version of the problem:
SomeClass c = (SomeClass) obj.getSomeClassParent()
not always but it happens sometimes to trigger exception
org.somepackage.SomeClass can't be cast to org.somepackage.SomeClass
How is this possible ? I suppose it has something to do with the fact that JAI imageio is native lib, but relay how can this happen ? I'm probably missing something but what ?
I'm using JAI imageio version 1.1
dcm4che 2.0.21 DICOM lib
Here is the original code
ImageInputStream iis = ImageIO.createImageInputStream(src);
Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM");
ImageReader reader = iter.next();
DicomImageReadParam param = (DicomImageReadParam) reader.getDefaultReadParam();
And the original exception
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
就会发生这种情况
SomeClass
实例(因此它的类是 CL X 的SomeClass
或我们称之为:CL(X)), 。 SomeClass
),SomeClass
实际上是CL(Y).SomeClass
所以你有:
CL(X).SomeClass
code>CL(Y).SomeClass
或者换句话说 - 不是同一个类 - 因此类转换异常。
可能重复: ClassCastException 转换为同一类时 - 它有还有一些好的建议。
I think it can happen if
SomeClass
instance was loaded from ClassLoader X (so its class isSomeClass
of CL X or let's call it:CL(X).SomeClass
)SomeClass
is actuallyCL(Y).SomeClass
So you have:
CL(X).SomeClass
CL(Y).SomeClass
Or in other words - not the same class - thus the class cast exception.
Possible duplicate of: ClassCastException when casting to the same class - it has some good suggestions as well.
我猜你会因为类加载器和本机库之间的不匹配而遇到问题。本机库被加载并与类加载器关联,但是,程序只能真正加载本机库的一个实例。因此,如果您在类加载器 A 中加载本机库,并且它输出的类将与类加载器 A 关联。如果您稍后在类加载器 B 中加载相同的本机库,您实际上并没有再次加载它,它仍然会为类加载器 A 传递类。因此,要么重新部署 Web 应用程序,要么在同一个 Web 服务器中有 2 个使用相同本机库的 Web 应用程序。
如果可能,您应该尝试将本机库放在 Web 服务器的基类路径中,以便基类加载器加载它,从而可供任何 Web 应用程序使用。如果你不能这样做,并且问题只是重新部署问题,那么你可能需要取消部署并在重新部署之前稍等一下(理论上,当与其关联的类加载器被GCed时,本机库将被卸载,但当然,这可能需要未知的时间)。
i would guess that you have a problem due to the mismatch between classloaders and native libraries. native libraries are loaded and associated with a classloader, however, the programs can only really load one instance of a native library. so, if you load the native lib in classloader A, and classes which it outputs will be associated with classloader A. if you later load the same native library in classloader B, you aren't really loading it again, and it will still be passing out classes for classloader A. so, either you redeployed your webapp, or you have 2 webapps in the same webserver which use the same native library.
if possible, you should try to put the native library in the base classpath of the webserver, so that it will be loaded by the base classloader, and thus be usable by any webapp. if you can't do this, and the problem is only a redeployment issue, then you might want to undeploy and wait a bit before redeploying (in theory, the native lib will be unloaded when the classloader with which it is associated is GCed, but of course, this can take an unknown amount of time).
奇怪的是,您尝试将其转换为它扩展的对象,不确定它是否具有您需要的功能,但可能值得尝试看看它是否仍然抛出异常。
Strange have you tried casting it to a Object it extends, not sure if it has the functionality you require but might be worth trying to see if it still throws the exception.
从图像中我看到它看起来像一个网络应用程序。我读了“卡塔琳娜”。所以很有可能这是一个纯粹的类加载问题。
例如,如果从 ImageIO 类获取的 ImageReader 是由不同的类加载器加载的(可能是因为它部署在不同的 web 应用程序中),则可能会发生这种情况,因此 getDefaultReadParam() 方法返回的 DicomImageReadParam 对象是 - 的实例从技术上讲-不同的类别。
From the image I see that it looks like a web application. I read 'catalina'. So there is a big chance, that it is a pure classloading problem.
It could happen, for example, if the ImageReader you get from the ImageIO class was loaded by a different classloader (maybe because it's deployed in a different webapp), so the DicomImageReadParam object returned by the getDefaultReadParam() method is an instance of a - technically spoken - different class.