2012-03-15 4 views
4

Мы выполняем POC в нашем проекте, где мы отправляем запрос на основе SOAP и соответственно получаем ответ SOAP от веб-службы. Мы стремимся использовать шаблон webservices (клиентский API), предоставляемый Spring Framework в нашем приложении. В соответствии с нашей архитектурой мы создаем пакет совместимых с OSGI (для нашего кода, который использует API шаблонов веб-сервисов для взаимодействия с веб-службой), который затем развертывается в контейнере Apache Felix. Мы также установили все зависимые пакеты, совместимые с OSGI, в контейнере Felix, чтобы разрешить все зависимости.Как динамически загружать классы Java в Runtime в OSGI?

В соответствии с шаблоном webservices отправителем сообщения службы веб-службы по умолчанию является HttpUrlConnectionMessageSender, который динамически загружается во время выполнения загрузчиком класса. По моему пониманию, мы получаем следующее исключение, потому что контейнер Felix не может загрузить класс из зависимого пакета OSGI (пакет веб-сервисов содержит HttpUrlConnectionMessageSender). Пожалуйста, обратитесь к журналам исключений ниже.

* org.springframework.beans.factory.BeanInitializationException: Could not find default strategy class for interface [org.springframework.ws.transport.WebServiceMessageSender]; nested exception is java.lang.ClassNotFoundException:org.springframework.ws.transport.http.HttpUrlConnectionMessageSender at org.springframework.ws.support.DefaultStrategiesHelper.getDefaultStrategies(DefaultStrategiesHelper.java:126) 

    at org.springframework.ws.support.DefaultStrategiesHelper.getDefaultStrategies(DefaultStrategiesHelper.java:90) 

    at org.springframework.ws.client.core.WebServiceTemplate.initMessageSenders(WebServiceTemplate.java:320) 

    at org.springframework.ws.client.core.WebServiceTemplate.initDefaultStrategies(WebServiceTemplate.java:306) 

    at org.springframework.ws.client.core.WebServiceTemplate.<init>(WebServiceTemplate.java:143) 

    at test.soapservice.service.SOAPServiceImpl.<init>(SOAPServiceImpl.java:40) 

    at test.soapservice.service.SOAPServiceActivator.start(SOAPServiceActivator.java:17) 

    at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:641) 

    at org.apache.felix.framework.Felix.activateBundle(Felix.java:1977) 

    at org.apache.felix.framework.Felix.startBundle(Felix.java:1895) 

    at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:944) 

    at org.apache.felix.gogo.command.Basic.start(Basic.java:729) 

Вызванный: java.lang.ClassNotFoundException: org.springframework.ws.transport.http.HttpUrlConnectionMessageSender

at java.net.URLClassLoader$1.run(URLClassLoader.java:200) 

    at java.security.AccessController.doPrivileged(Native Method) 

    at java.net.URLClassLoader.findClass(URLClassLoader.java:188) 

    at java.lang.ClassLoader.loadClass(ClassLoader.java:307) 

    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268) 

    at java.lang.ClassLoader.loadClass(ClassLoader.java:252) 

    at org.springframework.util.ClassUtils.forName(ClassUtils.java:211) 

    at org.springframework.util.ClassUtils.forName(ClassUtils.java:164) 

    at org.springframework.ws.support.DefaultStrategiesHelper.getDefaultStrategies(DefaultStrategiesHelper.java:114) 

По моему разумению, Феликс контейнер не может динамически загружать класс, используя ClassUtils .forName(), которое существует в другом пакете. Я рассматриваю это как проблему совместной работы, когда текущий пакет имеет другой загрузчик классов, а не загрузчик классов зависимого пакета.

У кого-то из этого сообщества столкнулись с тем же исключением? Если да, то какие шаги были предприняты вами для разрешения зависимостей класса времени выполнения? Пожалуйста, поделитесь своими мыслями/указателями, чтобы решить вышеупомянутую проблему. Быстрый ответ будет высоко оценен и может помочь нам сделать наш POC успешным.

Спасибо заранее, Mridul Чопра

+0

Вы определенно добавили 'org.springframework.ws.transport.http' в манифест? – artbristol

+0

Загрузка классов по имени не должна быть проблемой вообще, просто имейте в виду, что вы не можете использовать инструментарий проверки байта (bnd) для генерации вашего манифеста. Вам нужно будет настроить манифест и импортировать 'org.springframework.ws.transport.http', как говорит artbristol. Не могли бы вы показать свой манифест? –

ответ

0

в загрузку классов форме Class.forName() не проблема в любом OSGi контейнере. Проблема в том, что файл MANIFEST.MF не содержит правильных объявлений импорта. Один пакет должен экспортировать пакет org.springframework.ws.transport, а ваш пакет должен импортировать тот же пакет.

Если вы используете Maven для создания своего пакета, вы можете использовать Felix Bundle Plugin для генерации информации о правом манифестации.

<plugins> 
    <plugin> 
    <groupId>org.apache.felix</groupId> 
    <artifactId>maven-bundle-plugin</artifactId> 
    <extensions>true</extensions> 
    <configuration> 
     <instructions> 
     <Private-Package>my.private.package.*</Private-Package> 
     </instructions> 
    </configuration> 
    </plugin> 
</plugins> 

Это должно проверить ваш код и добавить импорт для чего-либо, что не находится в вашем «частном» пакете. Еще одна вещь, которую вы должны сделать, чтобы сделать эту работу, - установить тип packaging на bundle.

<packaging>bundle</packaging> 

Но приведенные выше примеры - это когда вы используете Maven в качестве инструмента построения. Если вы используете Gradle, вы можете использовать Gradle OSGi plugin для создания манифеста. Или, если вы используете Ant, вы можете использовать SpringSource Bundlor project (кстати, у него также есть плагин Maven).

+0

Фактически использование класса.forName() сильно обескуражено в OSGi.Я предлагаю, чтобы OP читал хорошую книгу об OSGi, как OSGi в действии http://www.amazon.com/OSGi-Action-Creating-Modular-Applications/dp/1933988916 – lothar

Смежные вопросы