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 также должно решить проблему, но этого не произошло.