Wildfly и Wildfly-swarm, внедряющие компоненты CDI из военного развертывания и настраиваемого модуля

В процессе экспериментов с Wildfly-swarm я столкнулся со странной ситуацией, связанной с инъекцией бобов.

У меня очень простой bean-компонент, примерно так:

@ApplicationScoped
public class FooServiceImpl implements FooService {
    Foo delegate;
    @PostConstruct public void init() {
        delegate = .....;
    }

    public Foo getFoo() {
        return delegate;
    }
}

Если я свяжу это в банку непосредственно во время развертывания войны, все будет работать нормально и, как ожидалось. Однако мне нужно, чтобы внутренние части этой реализации были полностью изолированы от приложения, поэтому я упаковал API службы и ее реализацию в отдельные модули jboss.

Эти модули добавляются в swarm uberJar, и мое приложение зависит от них через запись MANIFEST Dependencies. Теперь все работает нормально, bean-компонент FooService вводится в ресурсы сервлета / отдыха моего приложения, но метод init () не вызывается.

Я не могу понять, что здесь происходит. Это похоже на то, что процесс разрешения bean-компонентов не распознает аннотацию @ApplicationScope. Могут ли для него быть два разных загрузчика классов?

ОБНОВЛЕНИЕ

Я включил трассировку, и мне кажется, что Weld обрабатывает класс FooImpl как ApplicationScoped, т.е. добавляет LifecycleMixin.lifecycle_mixin_$$_postConstruct() к создаваемому прокси:

2017-09-14 23:11:34,315 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001538: Created context instance for bean Managed Bean [class com.xxx.FooImpl] with qualifiers [@Any @Default] identified as WELD%ManagedBean%test.war|test.war.external.file:/tmp/nestedjarloader2449602760983533131.tmp/META-INF/beans.xml|com.xxx.FooImpl|null|false
2017-09-14 23:11:34,315 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001542: Retrieving/generating proxy class com.xxx.FooImpl$Proxy$_$$_WeldClientProxy
2017-09-14 23:11:34,315 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public void com.xxx.FooImpl.registerMessageHandler(com.xxx.MessageHandler)
2017-09-14 23:11:34,315 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public void com.xxx.FooImpl.registerListeners(java.util.EventListener[])
2017-09-14 23:11:34,316 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public void com.xxx.FooImpl.send(com.xxx.MessageHandler,com.xxx.Message) throws java.io.IOException
2017-09-14 23:11:34,316 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public void com.xxx.FooImpl.init()
2017-09-14 23:11:34,316 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public java.lang.String java.lang.Object.toString()
2017-09-14 23:11:34,316 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public abstract void org.jboss.weld.interceptor.proxy.LifecycleMixin.lifecycle_mixin_$$_postConstruct()
2017-09-14 23:11:34,316 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public abstract void org.jboss.weld.interceptor.proxy.LifecycleMixin.lifecycle_mixin_$$_preDestroy()
2017-09-14 23:11:34,317 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001543: Created Proxy class of type class com.xxx.FooImpl$Proxy$_$$_WeldClientProxy supporting interfaces [interface com.xxx.FooService, interface java.io.Serializable, interface org.jboss.weld.interceptor.proxy.LifecycleMixin, interface org.jboss.weld.interceptor.util.proxy.TargetInstanceProxy, interface org.jboss.weld.bean.proxy.ProxyObject]
2017-09-14 23:11:34,317 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001506: Created new client proxy of type class com.xxx.FooImpl$Proxy$_$$_WeldClientProxy for bean Managed Bean [class com.xxx.FooImpl] with qualifiers [@Any @Default] with ID WELD%ManagedBean%test.war|test.war.external.file:/tmp/nestedjarloader2449602760983533131.tmp/META-INF/beans.xml|com.xxx.FooImpl|null|false
2017-09-14 23:11:34,318 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001507: Located client proxy of type class com.xxx.FooImpl$Proxy$_$$_WeldClientProxy for bean Managed Bean [class com.xxx.FooImpl] with qualifiers [@Any @Default]

Перехватчик постконструкции не вызывается - почему? Тайна углубляется!

ОБНОВЛЕНИЕ 2

Проверено это на vanilla wildfly, и поведение такое же, метод @PostConstruct не вызывается, если bean находится в модуле.


person forty-two    schedule 14.09.2017    source источник
comment
Если у вас есть API и Impl в отдельных модулях JBoss, то они действительно находятся в разных загрузчиках классов. Указывает ли module.xml для impl в МАНИФЕСТЕ, что он должен быть импортирован в загрузчик классов WAR?   -  person Ken    schedule 14.09.2017
comment
@ Кен Нет, не так ли? Я имею в виду, что я хочу использовать impl в своем собственном загрузчике классов, ApplicationScoped должен исходить только от одного загрузчика классов.   -  person forty-two    schedule 14.09.2017


Ответы (1)


Я полагаю, что этот вопрос и на форумах JBoss связаны, но если они не ...

Вероятная причина в том, что ваш отдельный модуль не заявляет о зависимости от <module name="javax.annotation.api"/>, откуда берется @PostConstruct. Добавление его должно решить проблему. Похоже, это ожидаемое поведение JVM (, как описано в этом SO question) - если вы пропустите зависимость во время выполнения, программа все равно будет выполняться, но игнорирует аннотацию.

Как способ обойти это (если вышеперечисленное не работает или вы не можете этого сделать) - вы можете использовать методы инициализатора. Это метод, выполняемый, как только объект создается CDI.

person Siliarus    schedule 26.09.2017
comment
Они действительно связаны :) - person forty-two; 26.09.2017