【发布时间】:2016-09-01 09:06:36
【问题描述】:
我们最近迁移到 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)
我们的配置:
- Tomcat 8.5.4
- CDI Weld 2.3.5.Final
- JSF 2.2.13
- Omnifaces 2.4
- Primefaces 6.0
- WEB-INF 中的一个空 beans.xml 文件
- 根 Web 应用程序上下文中的 BeanManager 资源条目
- Tomcat 由我们的 Java 代码启动(嵌入式使用)。
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 资源可能未正确配置。 (市场)
我不知道 Tomcat 更改日志中报告的此 Web 应用程序的初始化阶段问题是否与我们遇到的问题有关。从上下文中移除 BeanManager 资源解决问题的原因仍不清楚。
有什么想法吗?
【问题讨论】:
-
我可以解释 OmniFaces 2.4 中
的(非)必要性,但你能试试 OmniFaces 2.5-SNAPSHOT 吗?在该版本中,几乎所有 CDI 初始化都进行了重新设计/改进:github.com/omnifaces/omnifaces/issues/281,它对我来说效果很好。 -
使用 8 月 31 日构建的 omnifaces-2.5 快照版本,我们的 Web 应用程序正确启动,无论是否将
条目添加到 Web 上下文。但是,我很想知道为什么我们必须在 2.4 版本中删除 条目:) -
好的,你能说出异常的根本原因吗?
-
很遗憾没有。我感觉这是一个竞争条件问题,好像omnifaces 试图在将bean 管理器实际添加到JNDI 之前访问它。事实是,omnifaces 2.5 的最新快照没有问题,当且仅当我不在 Web 应用程序的上下文中添加
条目时,omnifaces 2.4 也没有问题。 -
堆栈跟踪中没有根本原因?那很奇怪。应该有一个 IllegalArgumentException 指示初始化失败的确切原因。