2015-04-18 2 views
1

Я пытаюсь сделать что-то, что может быть против спецификации J2EE. У меня разные банки, содержащие конечные точки cxf соответственно.Один сервлет CXF для нескольких конечных точек CXF в разных войнах

Я создал веб-проект с CXFServlet и развернул его на сервере JBoss 7. Когда я развертываю другие банки, они не могут зарегистрировать свои конечные точки CXF в CXFServlet, так как они недоступны для них.

Я хочу как-то предоставить CXFServlet в качестве службы, чтобы при загрузке маршрута для других банок во время развертывания автоматически конечные точки CXF должны были регистрироваться в этом CXFServlet.

Я знаю о понятиях CrossContext, RequestDispatcher, но они управляются отдельными проектами, когда мы запускаем сервлет этих проектов. Но в моем случае, как только проект будет развернут, маршрут CXF будет загружен, и конечная точка будет искать любой CXFServlet, и если он не найден, он не будет зарегистрирован.

ответ

0

Я предполагаю, что вы подразумевали раздельные автономные ВОЙНЫ, развернутые автономно или в разных ОУ.

Помните, что CXF встроен в JBoss, поэтому, возможно, вам не нужна такая динамическая регистрация - если речь идет только о конфигурации.

К сожалению, вы не можете легко выполнять такую ​​динамическую регистрацию с помощью отдельных ВОЙН. Я провел некоторое исследование.

Прежде всего, для выполнения этой работы библиотека CXF должна быть загружена из JBoss-библиотек, а не из каталога lib вашего веб-приложения. Это потому, что у WARs есть отдельные загрузчики классов. При загрузке классов эти загрузчики классов обращаются к их родителям, но никогда не относятся к другому загрузчику классов WAR. Даже если в обеих WAR были встроены банки CXF, результирующие классы были бы несовместимы - класс CXFServlet, загруженный загрузчиком классов A, отличается от класса CXFServlet, загружаемого загрузчиком классов B, хотя оба класса загружаются из одного JAR.

Чтобы использовать JBoss встроенных CXF необходимо добавить jboss-deployment-structure.xml к WEB-INF со следующим содержанием:

<jboss-deployment-structure> 
<deployment> 
    <dependencies> 
    <module name="org.apache.cxf" services="import"> 
    <imports> 
    <include path="**" /> 
    </imports> 
    </module> 
    </dependencies> 
</deployment> 
</jboss-deployment-structure> 

Для запуска CXFServlet, которая требует рамки пружины, необходимо также добавить пружинные банки для установки JBoss и определить их как модули, как описано здесь: How can I use the external jars on JBoss 7?. Также необходимо добавить зависимость в jboss-deployment-structure.xml.

Если вы его запустили (поздравляю, я не смог это сделать: /), то вы можете попробовать играть по умолчанию по шине, возвращенной org.apache.cxf.BusFactory.getDefaultBus(). Например, ваша главная WAR с CXFServlet может установить эту шину по умолчанию, и другие модули могут ее восстановить. Но я на 99% уверен, что вместо получения BusFactory из CXF вы получите org.jboss.wsf.stack.cxf.client.configuration.JBossWSBusFactory. Этот «усилен» JBoss, поэтому вы не сможете получить общий объект Bus, но другой для . Чтобы изменить это, вы должны создать в каждой WAR следующий файл: META-INF/services/org.apache.cxf.bus.factory с контентом: org.apache.cxf.BusFactory. Это должно быть в состоянии перезаписать фабрику шины JBoss с CXF по умолчанию.

ОК, поэтому теперь мы сможем получить общую шину. Я не тестировал это, но с помощью шины вы должны иметь возможность добавлять новые сервисы. Для этого нет очевидного API, но, возможно, что-то вроде этого будет работать: bus.getExtension(WSDLManager.class).addDefinition(implementor, definition);.

Ухх, как вы видите, это всего лишь эскиз потенциального решения. Слишком много вещей, которые могут пойти не так. Задача непростая и определенно болезненна.

В качестве альтернативы вы можете попробовать использовать OSGi, который поддерживается JBoss 7. Вы устанавливаете пакеты, публикуете некоторые конечные точки. Некоторое введение в OSGi на JBoss можно найти here. И here - это подсказка, как начать с CXF и OSGi на JBoss. Но опять же, это не очень популярный способ использования JBoss, поэтому не ожидайте большой поддержки.


EDIT: Это может быть также интересным для вас, почему автоматическое обнаружение cxf.xml файлов не работает. CXFServlet использует currentClassloader.getResourceAsStream(..), чтобы проверить, существует ли cxf.xml. Если cxf.xml находится в другой WAR, тогда текущий загрузчик классов не сможет его найти.

+0

Привет, Давид, Спасибо за подробное объяснение. Я перехожу из OSGI в Java, поэтому мне нужно выяснить, как это сделать :) Я попробую ваше решение. –

+0

Я надеялся отговорить вас от попыток;). Сообщите нам, преуспели ли вы - это может помочь и кому-то другому. –

+0

Привет, Дэвид :) На данный момент это не сработало для меня. Я отправлю сообщение, когда получу правильное решение. Благодарю. –