Jetty Maven 插件(码头:运行 目标)+ Weld CDI + JSF 2.2 = ViewScoped bean 上的 NPE
Jetty Maven plugin (jetty:run goal) + Weld CDI + JSF 2.2 = NPE on ViewScoped beans
在 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.[=13 之间有什么区别=]
我尝试在 web.xml 中添加 "resource-env-ref" 条目并在各种 Jetty 的 xml 文件中创建 BeanManager(jetty.xml、jetty-env.xml、 jetty-context.xml) 但它并没有改变任何东西。
更新:
NPE发生在会话失效时;由于在 JSF 中没有注册 BeanManager,因此无法销毁 ViewScoped bean。请参阅下面的堆栈跟踪:
Caused by: java.lang.NullPointerException at
com.sun.faces.application.view.ViewScopeContextManager.destroyBeans(ViewScopeContextManager.java:171)
at
com.sun.faces.application.view.ViewScopeContextManager.sessionDestroyed(ViewScopeContextManager.java:339)
at
com.sun.faces.application.view.ViewScopeManager.sessionDestroyed(ViewScopeManager.java:369)
at
com.sun.faces.application.WebappLifecycleListener.sessionDestroyed(WebappLifecycleListener.java:181)
at
com.sun.faces.config.ConfigureListener.sessionDestroyed(ConfigureListener.java:399)
at
org.eclipse.jetty.server.session.AbstractSessionManager.removeSession(AbstractSessionManager.java:772)
at
org.eclipse.jetty.server.session.AbstractSession.invalidate(AbstractSession.java:326)
at
com.sun.faces.context.ExternalContextImpl.invalidateSession(ExternalContextImpl.java:783)
Dimitri 在码头项目上提出了一个错误:https://bugs.eclipse.org/bugs/show_bug.cgi?id=462179
错误包含对问题原因的完整描述。简而言之,Weld 使 BeanManager 可用于 JSF 的方式不适用于未组装的 webapps(mvn jetty:run 就是这种情况),仅适用于 war 文件(即 mvn jetty:run-war 会起作用)。
一月
只需使用您的 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) {
}
}
在 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.[=13 之间有什么区别=]
我尝试在 web.xml 中添加 "resource-env-ref" 条目并在各种 Jetty 的 xml 文件中创建 BeanManager(jetty.xml、jetty-env.xml、 jetty-context.xml) 但它并没有改变任何东西。
更新:
NPE发生在会话失效时;由于在 JSF 中没有注册 BeanManager,因此无法销毁 ViewScoped bean。请参阅下面的堆栈跟踪:
Caused by: java.lang.NullPointerException at com.sun.faces.application.view.ViewScopeContextManager.destroyBeans(ViewScopeContextManager.java:171) at com.sun.faces.application.view.ViewScopeContextManager.sessionDestroyed(ViewScopeContextManager.java:339) at com.sun.faces.application.view.ViewScopeManager.sessionDestroyed(ViewScopeManager.java:369) at com.sun.faces.application.WebappLifecycleListener.sessionDestroyed(WebappLifecycleListener.java:181) at com.sun.faces.config.ConfigureListener.sessionDestroyed(ConfigureListener.java:399) at org.eclipse.jetty.server.session.AbstractSessionManager.removeSession(AbstractSessionManager.java:772) at org.eclipse.jetty.server.session.AbstractSession.invalidate(AbstractSession.java:326) at com.sun.faces.context.ExternalContextImpl.invalidateSession(ExternalContextImpl.java:783)
Dimitri 在码头项目上提出了一个错误:https://bugs.eclipse.org/bugs/show_bug.cgi?id=462179
错误包含对问题原因的完整描述。简而言之,Weld 使 BeanManager 可用于 JSF 的方式不适用于未组装的 webapps(mvn jetty:run 就是这种情况),仅适用于 war 文件(即 mvn jetty:run-war 会起作用)。
一月
只需使用您的 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) {
}
}