在Web应用程序中使用以下(相当新闻)组件:
Jetty maven插件9.2.6.v20141205
焊接CDI 2.2.9.Final
Mojarra JSF 2.2.10
该应用程序的web.xml包含以下侦听器:
org.jboss.weld.environment.servlet.BeanManagerResourceBindingListener
com.sun.faces.config.ConfigureListener
第一个侦听器使用JNDI注册BeanManager。 第二个侦听器初始化JSF并在JNDI中查找BeanManager。
当jetty maven插件与" jetty:run-war"运行时,此设置完全正常。目标或当应用程序作为独立的嵌入式jetty运行时。
然而,使用" jetty:run"在第一个监听器中注册的BeanManager在JSF中不可见,导致ViewScoped bean上的NPE。
在我看来,这似乎是一个范围或可见性问题,但我无法弄清楚 - jetty:run和jetty:run-war之间有什么区别。
我尝试添加" resource-env-ref" web.xml中的条目以及在各种Jetty的xml文件(jetty.xml,jetty-env.xml,jetty-context.xml)中创建BeanManager,但它没有改变任何内容。
更新:
NPE在会话失效时发生;由于在JSF中没有注册BeanManager,ViewScoped bean无法销毁。见下面的堆栈跟踪:
引起:java.lang.NullPointerException at com.sun.faces.application.view.ViewScopeContextManager.destroyBeans(ViewScopeContextManager.java:171) 在 com.sun.faces.application.view.ViewScopeContextManager.sessionDestroyed(ViewScopeContextManager.java:339) 在 com.sun.faces.application.view.ViewScopeManager.sessionDestroyed(ViewScopeManager.java:369) 在 com.sun.faces.application.WebappLifecycleListener.sessionDestroyed(WebappLifecycleListener.java:181) 在 com.sun.faces.config.ConfigureListener.sessionDestroyed(ConfigureListener.java:399) 在 org.eclipse.jetty.server.session.AbstractSessionManager.removeSession(AbstractSessionManager.java:772) 在 org.eclipse.jetty.server.session.AbstractSession.invalidate(AbstractSession.java:326) 在 com.sun.faces.context.ExternalContextImpl.invalidateSession(ExternalContextImpl.java:783)
答案 0 :(得分:0)
Dimitri在码头项目上提出了一个错误:https://bugs.eclipse.org/bugs/show_bug.cgi?id=462179
该错误包含问题原因的完整描述。简而言之,Weld使BeanManager可用于JSF的方式不适用于未组装的webapps(mvn jetty:run就是这种情况),只有war文件(即mvn jetty:run-war才有效)。
扬
答案 1 :(得分:0)
只需在您的 web.xml 中添加此侦听器即可。我使用 openwebbeans 作为 CDI 容器,但似乎它应该与任何其他容器一起使用。
package com.devadmin.computec.config;
import com.sun.faces.RIConstants;
import javax.enterprise.inject.spi.CDI;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class CustomServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
sce.getServletContext().setAttribute(RIConstants.CDI_BEAN_MANAGER, CDI.current().getBeanManager());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}