0

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.

zobbo
  • 117
  • 2
  • 13
  • Before I start replicating, did you check the mojarra 2.3.9 source? It is open. Checked what is null? – Kukeltje May 21 '20 at 18:16
  • Oh and there is a mojarra 2.3.14, tried including that? Just for testing? – Kukeltje May 21 '20 at 18:23
  • For my first comment, You can run in debug mode and set breakpoints... – Kukeltje May 21 '20 at 18:36
  • It seems that websocket is null in this call: connected = websocket.isRendered() && websocket.isConnected(); – zobbo May 21 '20 at 18:39
  • First try with the commandButtons from the previous question but **WITH** ajax. Oh and tried adding an actual websockets endpoint? There is none... might be part of the problem, causing the component to not actually be added to the view, so the findComponent in the previous statement in the Mojarra source returns null – Kukeltje May 21 '20 at 18:41
  • I have a websocket endpoint enabled in web.xml if that's what you mean – zobbo May 21 '20 at 18:45
  • That is for enabling websockets in general. I mean a real endpoint With The Right Channel – Kukeltje May 21 '20 at 18:46
  • I tried the commandbuttons with ajax=true and they still worked. I'm not sure what you mean by adding a real websocket endpoint other than f:websocket tags – zobbo May 21 '20 at 18:53
  • Something server side has produce something to be received by the `f:websocket` which ends up client-side.. oh and uhhhhh... adding `ajax="true"` to an `h:commandButton` .... hmmmm https://stackoverflow.com/questions/15267958/pcommandbutton-vs-hcommandbutton – Kukeltje May 21 '20 at 19:02
  • I've added Ajax correctly to the commandlink and it replicates the issue when clicking on the page2 link. I also added a server side PushContext but it didn't seem to make any difference. – zobbo May 21 '20 at 19:11
  • Actually the commandlink with ajax seems to work ok, it only gives an NPE after I've navigated with the primefaces menu. So it seems to break the commandlink also. Very strange. – zobbo May 21 '20 at 19:38
  • And a `p:commandLink`? – Kukeltje May 21 '20 at 19:59
  • I get the same behaviour for p:commandlink, Page1 works ok, selecting Page2 causes the exception. I'm having a bit of trouble updating mojarra so not sure if that will fix it. – zobbo May 21 '20 at 20:08

0 Answers0