NullPointerException in WebSocket Endpoint (follow on from another NPE question I asked)

I was seeing an NPE when trying to connect to my Websocket Endpoint, which I asked about here: NullPointerException when authenticating WebSocket connection

Since my Websocket endpoint now uses the injected Context and Model Context, that NPE went away; however, I am now seeing a new one but only on certain XWiki deployments. My dev environment is a clean v13 install and it works fine. On a v12 that was upgraded to v13, I see the NPE. Maybe it’s not the upgrade that is the issue and it’s a race condition or something else but, that’s the only key difference I can point out right now.

The v13 being used is 13.10.5 across all instances.

The NPE being thrown is:

2022-07-13 09:56:50,705 [http-nio-8080-exec-3 - https://app.seekingbinary.com/kb/websocket/t725e89b91a72447dab483c204e54e/navmenu] ERROR c.x.x.XWiki                    - Failed to get URL for provided wiki [t725e89b91a72447dab483c204e54e]
java.lang.NullPointerException: null
        at org.xwiki.wiki.internal.descriptor.document.DefaultWikiDescriptorDocumentHelper.getDocument(DefaultWikiDescriptorDocumentHelper.java:187)
        at org.xwiki.wiki.internal.descriptor.document.DefaultWikiDescriptorDocumentHelper.getDocumentFromWikiId(DefaultWikiDescriptorDocumentHelper.java:101)
        at org.xwiki.wiki.internal.descriptor.DefaultWikiDescriptorManager.getById(DefaultWikiDescriptorManager.java:170)
        at com.xpn.xwiki.XWiki.getServletPath(XWiki.java:5477)
        at com.xpn.xwiki.web.XWikiServletURLFactory.addServletPath(XWikiServletURLFactory.java:349)
        at com.xpn.xwiki.web.XWikiServletURLFactory.createURL(XWikiServletURLFactory.java:312)
        at com.xpn.xwiki.web.XWikiDefaultURLFactory.createURL(XWikiDefaultURLFactory.java:52)
        at com.xpn.xwiki.web.XWikiDefaultURLFactory.createURL(XWikiDefaultURLFactory.java:46)
        at com.xpn.xwiki.user.impl.xwiki.XWikiAuthServiceImpl.getAuthenticator(XWikiAuthServiceImpl.java:131)
        at com.xpn.xwiki.user.impl.xwiki.XWikiAuthServiceImpl.checkAuth(XWikiAuthServiceImpl.java:235)
        at com.seekingbinary.xwiki.authn.CustomAuthenticationService.checkAuth(CustomAuthenticationService.java:27)
        at com.xpn.xwiki.XWiki.checkAuth(XWiki.java:4336)
        at org.xwiki.websocket.internal.DefaultWebSocketContext.createExecutionContext(DefaultWebSocketContext.java:149)
        at org.xwiki.websocket.internal.DefaultWebSocketContext.initialize(DefaultWebSocketContext.java:78)
        at org.xwiki.websocket.internal.XWikiEndpointConfigurator.modifyHandshake(XWikiEndpointConfigurator.java:68)
        at org.apache.tomcat.websocket.server.UpgradeUtil.doUpgrade(UpgradeUtil.java:227)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:78)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:63)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.xwiki.container.servlet.filters.internal.SavedRequestRestorerFilter.doFilter(SavedRequestRestorerFilter.java:208)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:111)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:132)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.base/java.lang.Thread.run(Thread.java:829)

Looking at the XWiki source I can see that DefaultWebSocketContext#createExecutionContext creates a stub context and calls checkAuth on the Authenticator on line 149. I think the problem is that the DefaultWikiDescriptorDocumentHelper.getDocument(DefaultWikiDescriptorDocumentHelper.java:187) requires the XWikiContext to have been set/initialised on the Execution; however, that hasn’t happened yet as it’s only on return of the DefaultWebSocketContext#createExecutionContext that the context that is created is set on the Execution (in DefaultWebSocketContext#initialize on line 105).

To be more specific…

  1. DefaultWebSocketContext#initialize is called, which calls…
  2. DefaultWebSocketContext#createExecutionContext, which calls…
  3. xcontext.getWiki().checkAuth(xcontext);, which eventually calls…
  4. DefaultWikiDescriptorDocumentHelper#getDocument, which calls…
  5. XWikiContext context = xcontextProvider.get();. (Line 186), which calls…
  6. XWikiContextProvider#get, which calls…
  7. XWikiContextProvider#getXWikiContext, which calls…
  8. ExecutionContext econtext = this.execution.getContext();, which I think is returning null, so the xcontextProvider.get(); returns null.
    • As the context object is null, Line 187 in DefaultWikiDescriptorDocumentHelper#getDocument fails with an NPE.
  9. (If it didn’t NPE) The stack unravels back to DefaultWebSocketContext#initialize (step 1), which calls…
  10. DefaultWebSocketContext#initialize(ExecutionContext context), which calls…
  11. this.execution.pushContext(context, false); - Which I think is too late in this process.

Does this look like I’m on the right track and there is a bug here or could there be something else going on? I’ll continue to dig as I’m surprised I am not seeing this on other environments so there is something I’m probably missing.

Thanks in advance!

Cheers

I think you can create a ticket for that one, personally I find it weird that DefaultWebSocketContext.createExecutionContext is calling XWiki.checkAuth but I don’t know much about this code. @mflorea would know better but he’s off these days.

Note that I created a ticket related to a NPE in DefaultWebSocketContext.createExecutionContext few weeks ago, but it was for a different reason apparently, see: [XWIKI-19630] NPE when restarting a wiki with a realtime editor session opened - XWiki.org JIRA.

Thanks @surli. I’ll wait to see if @mflorea has any comments just in case, otherwise I’ll raise an issue in Jira. I’ll try to get to the bottom of why it’s happening in one xwiki install but not others.

@surli / @mflorea I’ve created: [XWIKI-20009] NPE when establishing a WebSocket, context is null - XWiki.org JIRA

@mflorea Have you had by chance an opportunity to look at this issue at all?

Thanks in advance,
Alex