问题
I get a NullPointerException when navigating on a PrimeFaces menu item with ajax = true when JSF 2.3 websockets are present in the pages. Below is the exception:
java.lang.NullPointerException
at com.sun.faces.push.WebsocketFacesListener.processEvent(WebsocketFacesListener.java:100)
at javax.faces.event.SystemEvent.processListener(SystemEvent.java:123)
at javax.faces.event.ComponentSystemEvent.processListener(ComponentSystemEvent.java:110)
at com.sun.faces.application.applicationimpl.Events.processListenersAccountingForAdds(Events.java:295)
at com.sun.faces.application.applicationimpl.Events.invokeViewListenersFor(Events.java:210)
at com.sun.faces.application.applicationimpl.Events.publishEvent(Events.java:109)
at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:127)
at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:119)
at javax.faces.application.ApplicationWrapper.publishEvent(ApplicationWrapper.java:776)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:89)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:76)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:199)
at javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:708)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:451)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1540)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:297)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:167)
at org.glassfish.tyrus.servlet.TyrusServletFilter.doFilter(TyrusServletFilter.java:282)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:167)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:215)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:119)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:611)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:550)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:75)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:114)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:332)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:199)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:439)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:144)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:182)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:156)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:218)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:95)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:260)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:177)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:109)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:88)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:53)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:515)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:89)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:94)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:33)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:114)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:569)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:549)
at java.lang.Thread.run(Thread.java:748)
Here is the minimal reproducible code to replicate:
index.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:view>
<h:head>
<title>Test 5</title>
</h:head>
<h:body>
<div class="column side">
<h2>Side</h2>
<h:form>
<h:commandLink value="Page1" actionListener="#{menuViewTest.selectPageOne}" />
<h:commandLink value="Page2" actionListener="#{menuViewTest.selectPageTwo}" />
</h:form>
<h:form>
<p:menu>
<p:submenu label="Menu">
<p:menuitem value="Page1" update="optionPanel" ajax="true" actionListener="#{menuViewTest.selectPageOne}"/>
<p:menuitem value="Page2" update="optionPanel" ajax="true" actionListener="#{menuViewTest.selectPageTwo}"/>
</p:submenu>
</p:menu>
</h:form>
</div>
<div class="column middle">
<h2>Middle</h2>
<p:outputPanel id="optionPanel" deferred="false">
<ui:include src="#{menuViewTest.view}">
</ui:include>
</p:outputPanel>
</div>
</h:body>
page1.xhtml:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<script type="text/javascript">
function notifyListener(message, channel, event) {
console.log("notifyListener message: " + message);
console.log("notifyListener channel: " + channel);
console.log("notifyListener event: " + event);
}
</script>
<h2>Page 1</h2>
<f:websocket channel="notify" onmessage="notifyListener" />
page2.xhtml:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<script type="text/javascript">
function notifyListener(message, channel, event) {
console.log("notifyListener message: " + message);
console.log("notifyListener channel: " + channel);
console.log("notifyListener event: " + event);
}
</script>
<h2>Page 2</h2>
<f:websocket channel="notify2" onmessage="notifyListener" />
MenuViewTest:
@Named("menuViewTest")
@SessionScoped
public class MenuViewTest implements Serializable {
private static final long serialVersionUID = -1015364935820045523L;
private String view;
private static final Logger logger = Logger.getLogger("politse.web.MenuView");
public void selectPageOne() {
setView("page1.xhtml");
}
public void selectPageTwo() {
setView("page2.xhtml");
}
public String getView() {
return view;
}
public void setView(String view) {
this.view = view;
}
public String getSelectPageOne(){
return "page1.xhtml";
}
public String getSelectPageTwo(){
return "page2.xhtml";
}
}
Changing the p:menuitem atrributes ajax to false fixes the issue, but I'm not sure why that is.
Tested on GlassFish 5.1.0 with JSF 2.3 and Mojarra 2.3.9.
来源:https://stackoverflow.com/questions/61939673/jsf-2-3-websockets-throw-a-nullpointerexception-when-using-primefaces-menuitem-w