Как получить объект-пакет, возвращаемый службой, из среды Equinox — java.lang.LinkageError

У меня есть класс, который запускает фреймворк Equinox. Теперь я хотел бы получить объект (определенный в одном из пакетов), который возвращается службой из фреймворка.

К сожалению, я получаю LinkageError и понятия не имею, как от нее избавиться. Можно ли вообще позволить службе возвращать правильный объект в код, не входящий в комплект?

Вот полная история:

ParserDTOBundle — это пакет, определяющий класс ParserDTO и экспортирующий соответствующий пакет.

В другом пакете, ParserServiceBundle, я определяю службу ParserService. Этот пакет импортирует пакет ParserDTO. Функция getDTO() службы ParserService создает новый объект ParserDTO и возвращает его.

Теперь я создал еще один класс, который запускает фреймворк Equinox и загружает оба пакета из каталога:

...
EclipseStarter.setInitialProperties(frameworkPropertiesMap);
bundleContext = EclipseStarter.startup(new String[] { "-console", "-dev", "bin" }, null);

bundleContext.installBundle("file:/" + dir + "ParserDTOBundle-0.0.1-SNAPSHOT.jar");
Bundle service = bundleContext.installBundle("file:/" + dir + "ParserServiceBundle-0.0.1-SNAPSHOT.jar");
service.start();

ServiceReference serviceReference = bundleContext.getServiceReference(ParserService.class.getName());

if (serviceReference != null) {
     ParserService ps = (ParserService) bundleContext.getService(serviceReference);
     if (ps != null) {
          ParserDTO dto = ps.getDTO();
          System.out.println(dto.getValue());
     }
 }

Вышеописанный класс является частью проекта Maven, не входящего в комплект. Запуск вышеуказанного класса завершается с ошибкой:

Exception in thread "main" java.lang.LinkageError: loader constraint violation: loader (instance of sun/misc/Launcher$AppClassLoader) previously initiated loading for a different type with name "de/ParserDTO"

Интересно, что я получаю эту ошибку в System.out.println, а не в предыдущей строке. Загрузчик класса ParserDTO в моем основном классе явно отличается от загрузчика класса объекта dto.

Как я могу получить информацию, хранящуюся в dto?? Это вообще возможно?? Должен ли я 1.) передать мой обычный загрузчик классов в пакет или 2.) вместо этого использовать базовые типы данных или 3.) каким-то совершенно другим способом??

Спасибо всем заранее! Себастьян


person user1488793    schedule 10.07.2012    source источник


Ответы (1)


Таким образом, класс ParserDTO был независимо загружен двумя разными загрузчиками классов: одним внутри вашего пакета и загрузчиком классов приложения из вашего «внешнего» приложения. Вам нужно убедиться, что он загружается только одним загрузчиком классов.

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

Однако в этом случае вы взаимодействуете между внешним приложением и пакетами внутри OSGi. Существует жесткое правило: платформа OSGi не может импортировать пакеты из пакетов внутри OSGi. Таким образом, пакет должен присутствовать во внешнем приложении и экспортироваться из системного пакета путем добавления его в FRAMEWORK_SYSTEMPACKAGES_EXTRA. Также убедитесь, что пакет импортирует этот пакет, а не имеет собственную копию.

Кстати... вы можете выбрать лучшее имя для пакета, чем просто de! Я не думаю, что вы единственный разработчик Java в Германии, поэтому вы не владеете этим пространством имен ;-)

person Neil Bartlett    schedule 10.07.2012
comment
Спасибо! В этом была проблема. После установки пакета DTO в карту свойств фреймворка с помощью FRAMEWORK_SYSTEMPACKAGES_EXTRA он работает нормально. Системную связку я всегда игнорирую, но теперь, думаю, повнимательнее присмотрюсь к ее настройкам. Еще раз спасибо. - person user1488793; 10.07.2012
comment
Я всегда сокращаю имена переменных, имена классов, а также пространства имен, чтобы сделать все более читаемым;) - person user1488793; 10.07.2012
comment
Здорово. Когда вы взаимодействуете между OSGi и внешним приложением, вы не можете игнорировать системный пакет, потому что именно там происходит взаимодействие. - person Neil Bartlett; 11.07.2012