Проблемы с кастингом Java / загрузчиком классов


Вот упрощенная версия задачи:

 SomeClass c = (SomeClass) obj.getSomeClassParent()

Не всегда, но иногда случается вызвать исключение

 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<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

Изображение Исключения http://img215.imageshack.us/img215/3894/exception.jpg

4 3

4 ответа:

Я думаю, что это может произойти, если

  1. экземпляр SomeClass был загружен из ClassLoader X (поэтому его класс является SomeClass CL X или назовем его: CL(X).SomeClass)
  2. но он отлит в другом загрузчике класса. Например, текущий загрузчик класса Threads - Y, поэтому SomeClass на самом деле CL(Y).SomeClass

Итак, у вас есть:

  • класс экземпляра = CL(X).SomeClass
  • класс cast target = CL(Y).SomeClass

Или другими словами-не тот же самый класс-таким образом, класс бросил исключение.


Возможный дубликат: ClassCastException при приведении к тому же классу - у него также есть несколько хороших предложений.

Я бы предположил, что у вас есть проблема из-за несоответствия между загрузчиками классов и собственными библиотеками. нативные библиотеки загружаются и ассоциируются с загрузчиком классов, однако программы могут толькореально загрузить один экземпляр нативной библиотеки. таким образом, если вы загружаете собственную библиотеку lib в classloader A, и классы, которые она выводит, будут связаны с classloader A. Если вы позже загружаете ту же собственную библиотеку в classloader B, вы на самом деле не загружаете ее снова, и она все равно будет раздача классов для classloader A. Итак, либо вы повторно развернули свое веб-приложение, либо у вас есть 2 веб-приложения на одном веб-сервере, которые используют одну и ту же собственную библиотеку.

Если это возможно, вы должны попытаться поместить нативную библиотеку в базовый путь к классу веб-сервера, чтобы она была загружена базовым загрузчиком классов и, таким образом, могла использоваться любым веб-приложением. если вы не можете этого сделать, и проблема заключается только в перераспределении, то вы можете отменить развертывание и немного подождать перед повторным развертыванием (теоретически, родной lib будет выгружен, когда загрузчик классов, с которым он связан, будет GCed, но, конечно, это может занять неизвестное количество времени).

Странно, вы пробовали привести его к объекту, который он расширяет, не уверен, что он имеет функциональность, которую вы требуете, но, возможно, стоит попробовать увидеть, если он все еще вызывает исключение.

Из изображения я вижу, что это похоже на веб-приложение. Я читал "Каталину". Так что есть большой шанс,что это чисто классовая проблема.

Это может произойти, например, если ImageReader, полученный из класса ImageIO, был загружен другим загрузчиком классов (возможно, потому, что он развернут в другом веб - приложении), поэтому объект DicomImageReadParam, возвращаемый методом getDefaultReadParam (), является экземпляром - технически выраженного-другого класса.