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…
DefaultWebSocketContext#initialize
is called, which calls…DefaultWebSocketContext#createExecutionContext
, which calls…xcontext.getWiki().checkAuth(xcontext);
, which eventually calls…DefaultWikiDescriptorDocumentHelper#getDocument
, which calls…XWikiContext context = xcontextProvider.get();
. (Line 186), which calls…XWikiContextProvider#get
, which calls…XWikiContextProvider#getXWikiContext
, which calls…ExecutionContext econtext = this.execution.getContext();
, which I think is returning null, so thexcontextProvider.get();
returns null.- As the
context
object is null, Line 187 inDefaultWikiDescriptorDocumentHelper#getDocument
fails with an NPE.
- As the
- (If it didn’t NPE) The stack unravels back to
DefaultWebSocketContext#initialize
(step 1), which calls… DefaultWebSocketContext#initialize(ExecutionContext context)
, which calls…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