
[英]java.lang.IllegalStateException: CDI API is not available in this environment. at org.omnifaces.config.BeanManager
[英]fixing OmniFaces BeanManager initialization issues when Tomcat starts
我们最近已经迁移到Tomcat 8.5.4(从8.5.3)和Omnifaces 2.4(从2.3),并且我们还更改了Web应用程序中的一些功能。 从那时起,我们的Web应用程序不再启动,但日志中存在以下异常:
Exception sending context initialized event to listener instance of class org.omnifaces.ApplicationListener
java.lang.ExceptionInInitializerError
at org.omnifaces.ApplicationListener.checkCDIAvailable(ApplicationListener.java:77)
at org.omnifaces.ApplicationListener.contextInitialized(ApplicationListener.java:61)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4716)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5178)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
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)
Caused by: java.lang.IllegalStateException: CDI BeanManager instance is not available in JNDI.
at org.omnifaces.config.BeanManager.<init>(BeanManager.java:100)
at org.omnifaces.config.BeanManager.<clinit>(BeanManager.java:49)
... 11 more
Caused by: java.lang.IllegalStateException: javax.naming.NamingException: WELD-001300: Unable to locate BeanManager
at org.omnifaces.util.JNDI.lookup(JNDI.java:95)
at org.omnifaces.config.BeanManager.<init>(BeanManager.java:96)
... 12 more
Caused by: javax.naming.NamingException: WELD-001300: Unable to locate BeanManager
at org.jboss.weld.resources.ManagerObjectFactory.getObjectInstance(ManagerObjectFactory.java:62)
at org.apache.naming.factory.FactoryBase.getObjectInstance(FactoryBase.java:94)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at org.apache.naming.NamingContext.lookup(NamingContext.java:840)
at org.apache.naming.NamingContext.lookup(NamingContext.java:160)
at org.apache.naming.NamingContext.lookup(NamingContext.java:828)
at org.apache.naming.NamingContext.lookup(NamingContext.java:160)
at org.apache.naming.NamingContext.lookup(NamingContext.java:828)
at org.apache.naming.NamingContext.lookup(NamingContext.java:174)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:163)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at org.omnifaces.util.JNDI.lookup(JNDI.java:90)
... 13 more
Exception sending context initialized event to listener instance of class com.sun.faces.config.ConfigureListener
java.lang.RuntimeException: java.lang.NoClassDefFoundError: Could not initialize class org.omnifaces.config.BeanManager
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:292)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4714)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5178)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
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)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.omnifaces.config.BeanManager
at org.omnifaces.util.Beans.getManager(Beans.java:88)
at org.omnifaces.util.Beans.getReference(Beans.java:113)
at org.omnifaces.application.OmniApplication.<init>(OmniApplication.java:70)
at org.omnifaces.application.OmniApplicationFactory.createOmniApplication(OmniApplicationFactory.java:89)
at org.omnifaces.application.OmniApplicationFactory.getApplication(OmniApplicationFactory.java:54)
at com.sun.faces.application.InjectionApplicationFactory.getApplication(InjectionApplicationFactory.java:93)
at com.sun.faces.config.InitFacesContext.getApplication(InitFacesContext.java:142)
at com.sun.faces.lifecycle.ClientWindowFactoryImpl.<init>(ClientWindowFactoryImpl.java:62)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at javax.faces.FactoryFinderInstance.getImplGivenPreviousImpl(FactoryFinderInstance.java:405)
at javax.faces.FactoryFinderInstance.getImplementationInstance(FactoryFinderInstance.java:251)
at javax.faces.FactoryFinderInstance.getFactory(FactoryFinderInstance.java:543)
at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:283)
at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:328)
at com.sun.faces.config.processor.FactoryConfigProcessor.process(FactoryConfigProcessor.java:236)
at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:439)
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:227)
我们的配置:
BeanManager资源条目:
<Resource name="BeanManager"
auth="Container"
type="javax.enterprise.inject.spi.BeanManager"
factory="org.jboss.weld.resources.ManagerObjectFactory"/>
我们已回到Tomcat 8.5.3和omnifaces 2.3,并尝试了不同的组件版本组合(8.5.3和2.4、8.5.4和2.3等等),以确定问题的根本原因。 ,但无济于事。
最后,我们怀疑所有这些组件(Tomcat,Weld,Onmnifaces等)的初始化之间都存在赛车条件问题。
最后,我从上下文XML文件中删除了BeanManager资源条目。
从上下文中删除:
<Resource name="BeanManager"
auth="Container"
type="javax.enterprise.inject.spi.BeanManager"
factory="org.jboss.weld.resources.ManagerObjectFactory"/>
它解决了这个问题。
我查看了Tomcat 8.5.4的更改日志,可以找到此更改:
在Web应用程序的初始化阶段,请勿尝试启动Web资源,因为此时Web应用程序尚未完全配置,并且Web资源可能未正确配置。 (Markt的)
我不知道Tomcat更改日志中报告的此Web应用程序的初始化阶段问题是否可以链接到我们遇到的问题。 从上下文中删除BeanManager资源解决了该问题的原因仍不清楚。
任何想法?
javax.naming.NamingException:WELD-001300:无法找到BeanManager
这基本上意味着找到了BeanManager
JNDI资源定义(如context.xml
所定义),但是尚未创建JNDI资源后面的具体BeanManager
实例。
这确实与Tomcat 8.5.4中描述的更改匹配。
在Web应用程序的初始化阶段,请勿尝试启动Web资源,因为此时Web应用程序尚未完全配置,并且Web资源可能未正确配置。 (Markt的)
我无法说出马克·托马斯 ( Mark Thomas)做出此决定的理由,而且背后也没有任何问题联系。 我猜他在努力避免由于潜在的初始化顺序问题而导致的间歇性中断部署而造成的混乱行为。 这也许是一件好事,但我认为Mark实际上忽略了通过web.xml
和web-fragment.xml
文件中的<ordering>
元素定义初始化顺序的可能性。 我确实记得,Tomcat从来没有考虑过@WebListener
或以编程方式创建的实例的调用顺序(但是对于<listener>
声明的实例却是如此)。 也许Mark最好修复该部分,而不是在初始化阶段完全禁用JNDI。
至于OmniFaces 2.4中的更改,根据版本243,此版本向Weld特定的servlet上下文属性添加了一个后备。 当JNDI资源不存在并且Weld被用作CDI实现时,将使用此方法。 也就是说,Weld还在内部将BeanManager实例存储为servlet上下文属性,因此OmniFaces可以直接获取它而无需JNDI。 这意味着不再需要context.xml
。 在Tomcat 8.5.4中,您实际上也应该删除context.xml
因为OmniFaces 2.4仍会首先尝试检查JNDI资源,这最终将引发异常,因为Tomcat 8.5.4更改导致BeanManager
实例意外地不可用。
在OmniFaces 2.5中,已根据问题281 (说明了从CDI 1.0到1.1的迁移)对CDI初始化进行了重新设计和改进。 OmniFaces不再使用JNDI检查BeanManager
。 OmniFaces现在将使用CDI 1.1引入的CDI
API。
BeanManager beanManager = CDI.current().getBeanManager();
无论JNDI配置/初始化如何,此方法均有效。
OmniFaces 2.5尚未最终定稿,但2.5-RC1已于昨天在Maven Central上市。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.