OpenWebBeans + MyFaces + Tomcat = IllegalStateException

Я пытаюсь заставить OWB (с MyFaces & Primefaces) работать на Tomcat 8.0.33. Кажется, что независимо от того, как я настраиваю вещи, я получаю эту ошибку...

org.apache.myfaces.webapp.AbstractFacesInitializer.initFaces An error occured while initializing MyFaces: It's not allowed to call getBeans(Type, Annotation...) before AfterBeanDiscovery

... сопровождается этой трассировкой стека:

java.lang.IllegalStateException: It's not allowed to call getBeans(Type, Annotation...) before AfterBeanDiscovery
    at org.apache.webbeans.container.InjectableBeanManager.checkAfterBeanDiscoveryProcessed(InjectableBeanManager.java:402)
    at org.apache.webbeans.container.InjectableBeanManager.getBeans(InjectableBeanManager.java:121)
    at org.apache.myfaces.cdi.util.CDIUtils.lookup(CDIUtils.java:45)
    at org.apache.myfaces.flow.cdi.DefaultCDIFacesFlowProvider.getAnnotatedFlows(DefaultCDIFacesFlowProvider.java:51)
    at org.apache.myfaces.flow.impl.AnnotatedFlowConfigurator.configureAnnotatedFlows(AnnotatedFlowConfigurator.java:42)
    at org.apache.myfaces.config.FacesConfigurator.configureFlowHandler(FacesConfigurator.java:1666)
    at org.apache.myfaces.config.FacesConfigurator.configure(FacesConfigurator.java:608)
    at org.apache.myfaces.webapp.AbstractFacesInitializer.buildConfiguration(AbstractFacesInitializer.java:416)
    at org.apache.myfaces.webapp.Jsp21FacesInitializer.initContainerIntegration(Jsp21FacesInitializer.java:73)
    at org.apache.myfaces.webapp.AbstractFacesInitializer.initFaces(AbstractFacesInitializer.java:172)
    at org.apache.myfaces.webapp.StartupServletContextListener.contextInitialized(StartupServletContextListener.java:121)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4809)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5251)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1696)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:484)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:433)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1471)
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1312)
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1404)
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:832)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$256(TCPTransport.java:683)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Основываясь на том, что я прочитал здесь, здесь и здесь (и еще около пяти баджиллионов в других местах), я попробовал это с зависимостью плагина Tomcat, с прослушивателем OWB, указанным в web.xmlи даже с ними обоими. Кажется, что независимо от того, что я делаю, я не могу убедить OWB сделать свое дело до того, как MyFaces включится и начнет делать свое дело. Я что-то упускаю необычайно очевидное или что-то?

// Maven Dependencies
com.amazonaws:aws-java-sdk-dynamodb:1.10.72

org.apache.myfaces.core:myfaces-api:2.2.10
org.apache.myfaces.core:myfaces-impl:2.2.10

org.apache.openwebbeans:openwebbeans-spi:1.6.3
org.apache.openwebbeans:openwebbeans-impl:1.6.3
org.apache.openwebbeans:openwebbeans-web:1.6.3
org.apache.openwebbeans:openwebbeans-jsf:1.6.3
org.apache.openwebbeans:openwebbeans-el22:1.6.3
org.apache.openwebbeans:openwebbeans-tomcat7:1.6.3

org.apache.geronimo.specs:geronimo-atinject_1.0_spec:1.0
org.apache.geronimo.specs:geronimo-jcdi_1.1_spec:1.0
org.apache.geronimo.specs:geronimo-interceptor_1.2_spec:1.0
org.apache.geronimo.specs:geronimo-annotation_1.2_spec:1.0

javax.enterprise:cdi-api:1.2
javax.validation:validation-api:1.1.0.Final
org.hibernate:hibernate-validator:5.2.4.Final

org.primefaces:primefaces:5.3
org.primefaces.themes:dark-hive:1.0.10

com.google.guava:guava:19.0
com.google.code.gson:gson:2.5

org.jetbrains:annotations:15.0

2 ответа

Вы должны использовать ContextLifecycleListener.java

измените метод addOwbListeners() на ниже

private void addOwbListeners(StandardContext context) {
  String[] oldListeners = context.findApplicationListeners();
  LinkedList<String> listeners = new LinkedList<String>();

  // 3rd
  listeners.addFirst("org.apache.myfaces.webapp.StartupServletContextListener");
  // 2nd
  listeners.addFirst("org.apache.webbeans.web.tomcat7.ContextLifecycleListener");
  // 1st
  listeners.addFirst("org.apache.webbeans.servlet.WebBeansConfigurationListener");

  for (String listener : oldListeners) {
    listeners.add(listener);
    context.removeApplicationListener(listener);
  }

  for (String listener : listeners) {
    context.addApplicationListener(listener);
  }
}

этот класс загружается в общий загрузчик классов tomcat. не веб-приложение контекста загрузчик классов. https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

/META-INF/context.xml

<Context>
  <Listener className="mypackage.ContextLifecycleListener" />
  <Resource name="BeanManager" auth="Container"
    type="javax.enterprise.inject.spi.BeanManager"
    factory="org.apache.webbeans.container.ManagerObjectFactory" />
</Context>

/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app
  xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1" metadata-complete="false"
>
<servlet>
  <servlet-name>facesServlet</servlet-name>
  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>facesServlet</servlet-name>
  <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<resource-ref>
  <res-ref-name>BeanManager</res-ref-name>
  <res-type>javax.enterprise.inject.spi.BeanManager</res-type>
  <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</web-app>

У меня была такая же проблема с последними версиями продуктов: Tomcat 9.0.12, MyFaces 2.3.2 и OpenWebBeans 2.0.7.

В соответствии с документацией OpenWebBeans Добавление OpenWebBeans в ваш проект контейнера сервлетов, я добавил слушатель конфигурации в web.xml

<listener>
    <listener-class>org.apache.webbeans.servlet.WebBeansConfigurationListener</listener-class>
</listener>

и это решило проблему.

Обратите внимание, что согласно документации добавление плагина Tomcat7 также должно решить проблему, но этого не произошло.

Другие вопросы по тегам