#java #osgi #classloader
#java #osgi #classloader
Вопрос:
interface A
class B implements A
Я получаю ClassCastException при преобразовании B в A. Оба A и B находятся в одном пакете.
Это может быть из-за загрузчика классов. Почему изменяется загрузчик классов для одного и того же пакета? Как я могу справиться с этой проблемой?
Дополнительная информация
- интерфейс A (т.Е. AdminService) и класс реализации B (т.Е. AdminServiceImpl) находятся в одном пакете (fusion-core)
- Принимая во внимание, что приведение происходит в другом пакете. — Приведение не происходит напрямую. ie
B b = new B(); A a = (A) b;
не происходит. -
Приведение происходит путем разрешения службы в реестре служб OSGi. ie
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; }
Эпилог
Спасибо Ивану, Анджело и Би Джею. На самом деле указатель BJ помог мне устранить проблему.
В манифесте пакета, который пытался выполнить приведение, <EXPORT-PACKAGE>
экспортировался пакет другого пакета, который содержал интерфейс и реализацию. Из-за этого, вероятно, один и тот же байт-код загружался двумя разными загрузчиками классов. Bundle (выполняющий приведение), вероятно, предположил, что пакет является частью самого себя, и снова загрузил байт-код!!!
Большое спасибо, ребята.
Комментарии:
1. В каком пакете находится код, который пытается выполнить приведение? В том же пакете, что и «B» и «A», или это другой пакет?
2. Как говорит Иван, нам понадобится немного больше информации. Можете ли вы показать содержимое вашего пакета и его манифеста?
3. в будущем, пожалуйста, отредактируйте свой вопрос, а не включайте соответствующие детали в комментарии.
Ответ №1:
Если код, выполняющий приведение к A, загрузил A, отличный от пакета, который определил B (и содержит A, как вы указываете), то в виртуальной машине могут быть два разных класса A. Один из пакета, определяющего B, и другой, используемый пакетом, выполняющим приведение к A.
Поскольку A является общим типом, вам необходимо убедиться, что пакет, определяющий B, и пакет, приводящий к A, используют один и тот же класс A. Они оба должны либо импортировать пакет, содержащий A, из некоторого третьего пакета, либо пакет, определяющий B, должен экспортировать пакет, содержащий A, чтобы пакет, выполняющий приведение к A, мог импортировать этот пакет.