JBoss 6 + Spring 3.0.5 + JAX-WS/CXF

У нас есть наш проект, работающий на JBoss 6 с Spring 3.0.5. Все шло гладко, пока мы не попытались реализовать некоторые веб-сервисы с помощью JAX-WS. Если я попытаюсь сделать какой-нибудь простой WS (например, добавить 2 числа), это просто сработает - я добавлю аннотации и добавлю аннотированный класс в виде сервлета. Но все становится сложнее, если я пытаюсь заполнить свои классы JAX-WS зависимостями.

Вот мой код:

@WebService(name = "principal")
public class PrincipalWebService extends SpringBeanAutowiringSupport {

    @Autowired
    private PrincipalManager manager;

    @WebMethod
    public int add(int a, int b) {
        return a + b;
    }

    @WebMethod
    public Principal getById(int i) {
            return manager.getById(i);
    }

}

Метод добавления работает, но getById не работает с NPE. Я отлаживал SpringBeanAutowiringSupport, и похоже, что ContextLoader.getCurrentWebApplicationContext() возвращает значение null. Это означает, что конструктор SpringBeanAutowiringSupport вызывается до инициализации контекста.

Я пытался следовать инструкциям CXF по запуску приложения с помощью Spring. У меня сейчас нет этого кода, но я зарегистрировал PrincipalWebService как bean-компонент, создал файл Spring для настройки CXF и добавил этот bean-компонент через его идентификатор в качестве конечной точки. На Jetty все прошло хорошо, но на JBoss не получилось. Я получал разные виды исключений в зависимости от того, как я настраиваю CXF, но основная причина была одна и та же — версия JBoss 6 CXF скомпилирована для Spring 2.5, поэтому у нас была несогласованность библиотек.

Есть ли у кого-нибудь идеи о том, как заставить IoC работать с сервисами Jax-ws на JBoss 6?


person Yura Taras    schedule 18.03.2011    source источник


Ответы (3)


Хорошо, я нашел обходной путь. Все, что нам нужно сделать, это перенести внедрение зависимостей в метод @PostConstruct:

@PostConstruct
public void init() {
    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
person Yura Taras    schedule 18.03.2011
comment
Потрясающий! У вас такая же проблема, и вы попробовали ваше решение, и оно работает как шарм! Спасибо. Однако я немного удивлен, что это нужно сделать, поскольку в документации Spring указано, что все, что вам нужно сделать, это расширить SpringBeanAutowiringSupport, чтобы он заработал. Однако, как и вы, в JBoss 7, похоже, это не работает. - person Eric B.; 19.01.2012
comment
Но для меня ContextLoader.getCurrentWebApplicationContext() возвращает null в методе processInjectionBasedOnCurrentContext(). Так что все еще DI не работал. Любая идея? - person Manu; 05.09.2012
comment
Шикарное решение!! Большое спасибо. Я искал как сумасшедший решение, и это сработало просто отлично! Я использую Spring 3.2.0 и сообщество Jboss 6.0.0. - person Jose; 26.07.2013

Вы должны зарегистрировать свою конечную точку в контексте весны, используя jaxws: endpoint, и ссылаться на свой компонент, используя атрибут реализации. Например:

<jaxws:endpoint id="NotificationImpl"
                implementorClass="com.foo.ws.notification.NotificationImpl"
                implementor="#notificationImpl"
                serviceName="notification:Notification"
                address="/notification"
                xmlns:notification="http://notification.ws.foo.com">

Реализация конечной точки:

@Component("notificationImpl")
@WebService(endpointInterface="com.foo.ws.notification.Notification")
public class NotificationImpl implements Notification  {

  @Autowired MessagingService messagingService = null;

  //...
}
person sourcedelica    schedule 18.03.2011
comment
Конфигурация CXF XML не работала из-за несогласованности версий. У него были разные симптомы, такие как исключение из-за того, что пространство имен jaxws не зарегистрировано; но основной причиной была бинарная несовместимость между версиями. - person Yura Taras; 21.03.2011

У меня была такая же проблема, но в WebLogic, и я решил ее, как описано здесь https://jira.springsource.org/browse/SPR-5652 .

person bedla.czech    schedule 24.05.2013