This issue has been created
There are 2 updates.
 
 
XWiki Commons / cid:jira-generated-image-avatar-ca39a878-4a5a-4129-8671-3e6ea2270ace XCOMMONS-3752 Open

Job status REST endpoint can fail with a NullPointerException while the job is running

 
View issue   ·   Add comment
 

Issue created

 
cid:jira-generated-image-avatar-f176fcaf-f4f4-40f1-8289-9b4b00351128 Vincent Massol created this issue on 04/Sep/26 11:47
 
Summary: Job status REST endpoint can fail with a NullPointerException while the job is running
Issue Type: cid:jira-generated-image-avatar-ca39a878-4a5a-4129-8671-3e6ea2270ace Bug
Affects Versions: 17.10.12
Assignee: Unassigned
Components: Job
Created: 04/Sep/26 11:47
Priority: cid:jira-generated-image-static-major-da52a8a8-09fc-43ff-b668-90398d271a2d Major
Reporter: Vincent Massol
Description:

Problem

GET /rest/jobstatus/<id> can return an HTTP 500 with a NullPointerException while the job it reports on is still running:

java.lang.NullPointerException: Cannot invoke "org.xwiki.job.internal.DefaultJobProgressStep.getOffset()" because the return value of "org.xwiki.job.internal.DefaultJobProgressStep.getParent()" is null
	at org.xwiki.job.internal.DefaultJobProgress.getCurrentLevelOffset(DefaultJobProgress.java:250)
	at org.xwiki.rest.internal.ModelFactory.toRestJobProgress(ModelFactory.java:1251)
	at org.xwiki.rest.internal.ModelFactory.toRestJobStatus(ModelFactory.java:1218)
	at org.xwiki.rest.internal.resources.job.JobStatusResourceImpl.getJobStatus(JobStatusResourceImpl.java:47)

Any UI that polls job status while the job progresses can hit this, and the progress bar it feeds then breaks. It was observed in App Within Minutes: adding an application entry polls /rest/jobstatus/refactoring/create/..., that poll returned 500, the page never reloaded and the operation appeared to hang.

Cause

DefaultJobProgress#getCurrentLevelOffset() evaluates getCurrentStep() twice:

return getCurrentStep().getParent() != null ? getCurrentStep().getParent().getOffset() : getOffset();

currentStep is a plain, non-volatile field that the job thread reassigns as the job progresses, while the REST thread reads it. Between the null check and the dereference the job thread can advance the progress so that the second getCurrentStep() returns the root step, whose parent is null — the NPE therefore happens on the very line meant to guard against it.

The null check was added by XCOMMONS-1167 (9.1), and the double read has been there ever since, so every version from 9.1 onwards is affected. Being a race, it reproduces rarely.

Fix

Read the parent once:

DefaultJobProgressStep parent = getCurrentStep().getParent();
return parent != null ? parent.getOffset() : getOffset();

Occurrence

Seen on CI in XWiki Environment Tests / xwiki-platform / stable-18.4.x #113, where it made two App Within Minutes functional tests time out: LiveTableGeneratorIT.titleField and AppsLiveTableIT.testEditApplication.

 
 

2 updates

 
cid:jira-generated-image-avatar-f176fcaf-f4f4-40f1-8289-9b4b00351128 Changes by Vincent Massol on 04/Sep/26 11:47
 
Fix Version: 18.8.0-rc-1
Assignee: Vincent Massol