ClassCastException из-за проблемы загрузчика классов - PullRequest
2 голосов
/ 26 апреля 2011
interface A
class B implements A

Я получаю ClassCastException при приведении B к A. И A, и B находятся в одном комплекте.

Это может быть из-за загрузчика классов. Почему загрузчик классов меняется на один и тот же пакет? Как я могу справиться с этой проблемой?

Дополнительная информация

  • интерфейс A (т. Е. AdminService) и класс реализации B (т. Е. AdminServiceImpl) находятся в одном пакете (ядро fusion)
  • Принимая во внимание, что кастинг происходит в другой упаковке. - Кастинг не происходит напрямую. т.е. B b = new B(); A a = (A) b; не происходит.
  • Приведение происходит путем разрешения службы в реестре служб OSGi. то есть

    AdminService adminService = getService(AdminService.class.getName(), 100); 
    public T getService(String type, long timeToWait) { 
      ServiceTracker serviceTracker = serviceRegistry.get(type); 
      if (serviceTracker == null) { 
        serviceTracker = this.registerServiceTracker(type); 
      } 
      T service = null; 
      try { 
        service = (T) serviceTracker.waitForService(timeToWait); 
      } catch (InterruptedException e) { 
        logger.error("Error while fetching service", e); 
      } return service; 
    }
    

Эпилог

Спасибо, Иван, Анджело и Би Джей. На самом деле указатель Би Джей помог мне решить проблему.

В манифесте пакета, который пытался выполнить приведение, <EXPORT-PACKAGE> экспортировал пакет другого пакета, который содержал интерфейс и реализацию. Из-за этого, вероятно, один и тот же байт-код загружался двумя разными загрузчиками классов. Bundle (выполняя приведение), вероятно, предположил, что пакет является частью самого себя, и снова загрузил байт-код !!!

Большое спасибо, ребята.

1 Ответ

4 голосов
/ 26 апреля 2011

Если код, выполняющий приведение к A, загрузил другой A, чем пакет, который определил B (и содержит A, как вы указали), то в VM может быть два разных класса A. Один из связки, определяющей B, и другой, используемый связкой, выполняющей приведение к A.

Поскольку A является общим типом, вам необходимо убедиться, что пакет, определяющий B, и преобразование пакета в A оба используют один и тот же класс A. Они оба должны либо импортировать пакет, содержащий A, из некоторого 3-го пакета, либо из пакета. определение B должно экспортировать пакет, содержащий A, чтобы пакет, выполняющий приведение к A, мог импортировать этот пакет.

...