Skip to content

Conversation

@jimklimov
Copy link

See https://issues.jenkins.io/browse/JENKINS-76294, #180 and jenkinsci/lockable-resources-plugin#825 (for example of similar problem and fix).

Testing done

So far none. The BuildStatusAction.java does not seem to use a JenkinsRule so a new test class would be needed.

In fact, plugin tests failed for me locally even on the unmodified master branch, so a new failing (later fixed) test would be a bit invisible.

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests that demonstrate the feature works or the issue is fixed

…zed [JENKINS-76294]

Signed-off-by: Jim Klimov <jimklimov+jenkinsci@gmail.com>
…erialization [JENKINS-76294]

Signed-off-by: Jim Klimov <jimklimov+jenkinsci@gmail.com>
… them in constructor(s) [JENKINS-76294]

Signed-off-by: Jim Klimov <jimklimov+jenkinsci@gmail.com>
@jimklimov
Copy link
Author

For now, posting first the proposed solution to check it would not explode on Jenkins CI farm. As noted above, maven test crashed for me locally even on master branch anyway.

@jimklimov
Copy link
Author

jimklimov commented Nov 23, 2025

Apparently, current Jenkins CI farm can not build (pass tests of) the plugin too. Oh joy...

@jimklimov jimklimov changed the title Address ConcurrentModificationException which occasionally happens during XStream saving of running workflows Address ConcurrentModificationException which occasionally happens during XStream saving of running workflows [JENKINS-76294] Nov 27, 2025
@jimklimov
Copy link
Author

Test failures as such seem to not be related to the PR change, as there are relatively few of those in https://ci.jenkins.io/job/Plugins/job/github-autostatus-plugin/job/PR-181/1/pipeline-overview/log?nodeId=53 :

2025-11-21T15:06:28.708Z] [INFO] 
[2025-11-21T15:06:28.708Z] [ERROR] Errors: 
[2025-11-21T15:06:28.708Z] [ERROR] org.jenkinsci.plugins.githubautostatus.config.GithubNotificationConfigTest.testConfigBranchSource
[2025-11-21T15:06:28.708Z] [ERROR]   Run 1: GithubNotificationConfigTest.testConfigBranchSource:117 » NoClassDefFound com/...
[2025-11-21T15:06:28.708Z] [ERROR]   Run 2: GithubNotificationConfigTest.testConfigBranchSource:117 » NoClassDefFound com/...
[2025-11-21T15:06:28.709Z] [ERROR]   Run 3: GithubNotificationConfigTest.testConfigBranchSource:117 » NoClassDefFound com/...
[2025-11-21T15:06:28.709Z] [ERROR]   Run 4: GithubNotificationConfigTest.testConfigBranchSource:117 » NoClassDefFound com/...
[2025-11-21T15:06:28.709Z] [ERROR]   Run 5: GithubNotificationConfigTest.testConfigBranchSource:117 » NoClassDefFound com/...
[2025-11-21T15:06:28.709Z] [INFO] 
[2025-11-21T15:06:28.709Z] [ERROR] org.jenkinsci.plugins.githubautostatus.integration.DeclarativePipelineTest.testAbort
[2025-11-21T15:06:28.709Z] [ERROR]   Run 1: DeclarativePipelineTest.testAbort:306 NullPointer
[2025-11-21T15:06:28.709Z] [ERROR]   Run 2: DeclarativePipelineTest.testAbort:306 NullPointer
[2025-11-21T15:06:28.709Z] [ERROR]   Run 3: DeclarativePipelineTest.testAbort:306 NullPointer
[2025-11-21T15:06:28.709Z] [ERROR]   Run 4: DeclarativePipelineTest.testAbort:306 NullPointer
[2025-11-21T15:06:28.709Z] [ERROR]   Run 5: DeclarativePipelineTest.testAbort:306 NullPointer
[2025-11-21T15:06:28.709Z] [INFO] 
[2025-11-21T15:06:28.709Z] [INFO] 
[2025-11-21T15:06:28.709Z] [ERROR] Tests run: 252, Failures: 10, Errors: 2, Skipped: 0
[2025-11-21T15:06:28.709Z] [INFO] 
[2025-11-21T15:06:28.709Z] [ERROR] There are test failures.

The GithubNotificationConfigTest.testConfigBranchSource fails due to java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/util/JacksonFeature.

I am less certain about DeclarativePipelineTest.testAbort (which seems to get NPEs).

There are however about 400 mentions of writeReplace method added by this PR - apparently some mock is expected to cover it (and some other methods?) for the test runs. I am not sure if this actually causes problems, but at least is mentioned all around that test log (not just at the failed tests):

2025-11-21T15:05:16.574Z] [ERROR] org.jenkinsci.plugins.githubautostatus.integration.DeclarativePipelineTest.testCaughtExceptionSetStageFail  Time elapsed: 3.163 s  <<< FAILURE!
[2025-11-21T15:05:16.574Z] Wanted but not invoked:
[2025-11-21T15:05:16.575Z] buildStatusAction.updateBuildStatusForStage(
[2025-11-21T15:05:16.575Z]     "Before stage",
[2025-11-21T15:05:16.575Z]     CompletedSuccess,
[2025-11-21T15:05:16.575Z]     <any long>
[2025-11-21T15:05:16.575Z] );
[2025-11-21T15:05:16.575Z] -> at org.jenkinsci.plugins.githubautostatus.integration.DeclarativePipelineTest.testCaughtExceptionSetStageFail(DeclarativePipelineTest.java:230)
[2025-11-21T15:05:16.575Z] 
[2025-11-21T15:05:16.576Z] However, there were exactly 6 interactions with this mock:
[2025-11-21T15:05:16.576Z] buildStatusAction.writeReplace();
[2025-11-21T15:05:16.576Z] -> at com.thoughtworks.xstream.converters.reflection.SerializationMethodInvoker.callWriteReplace(SerializationMethodInvoker.java:89)
[2025-11-21T15:05:16.576Z] 
[2025-11-21T15:05:16.576Z] buildStatusAction.getJobName();
[2025-11-21T15:05:16.576Z] -> at org.jenkinsci.plugins.githubautostatus.BuildStatusJobListener.onCompleted(BuildStatusJobListener.java:74)
[2025-11-21T15:05:16.576Z] 
[2025-11-21T15:05:16.577Z] buildStatusAction.getRepoName();
[2025-11-21T15:05:16.577Z] -> at org.jenkinsci.plugins.githubautostatus.BuildStatusJobListener.onCompleted(BuildStatusJobListener.java:75)
[2025-11-21T15:05:16.577Z] 
[2025-11-21T15:05:16.577Z] buildStatusAction.getBranchName();
[2025-11-21T15:05:16.577Z] -> at org.jenkinsci.plugins.githubautostatus.BuildStatusJobListener.onCompleted(BuildStatusJobListener.java:76)
[2025-11-21T15:05:16.577Z] 
[2025-11-21T15:05:16.577Z] buildStatusAction.updateBuildStatusForJob(
[2025-11-21T15:05:16.578Z]     CompletedError,
[2025-11-21T15:05:16.578Z]     {"BUILD_OBJECT" = p #1, "TEST_CASE_INFO" = null, "REPO_NAME" = null, "BLOCKED_DURATION" = 0L, "JOB_DURATION" = 67L, "BRANCH_NAME" = null, "COVERAGE_INFO" = null, "JOB_NAME" = null}
[2025-11-21T15:05:16.578Z] );
[2025-11-21T15:05:16.578Z] -> at org.jenkinsci.plugins.githubautostatus.BuildStatusJobListener.onCompleted(BuildStatusJobListener.java:83)
[2025-11-21T15:05:16.578Z] 
[2025-11-21T15:05:16.578Z] buildStatusAction.writeReplace();
[2025-11-21T15:05:16.578Z] -> at com.thoughtworks.xstream.converters.reflection.SerializationMethodInvoker.callWriteReplace(SerializationMethodInvoker.java:89)
[2025-11-21T15:05:16.579Z] 
[2025-11-21T15:05:16.579Z] 
[2025-11-21T15:05:16.579Z] 	at org.jenkinsci.plugins.githubautostatus.integration.DeclarativePipelineTest.testCaughtExceptionSetStageFail(DeclarativePipelineTest.java:230)
[2025-11-21T15:05:16.579Z] 	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
[2025-11-21T15:05:16.579Z] 	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
[2025-11-21T15:05:16.579Z] 	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
[2025-11-21T15:05:16.579Z] 	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
[2025-11-21T15:05:16.579Z] 	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
[2025-11-21T15:05:16.580Z] 	at org.mockito.internal.junit.JUnitRule$1.evaluateSafely(JUnitRule.java:57)
[2025-11-21T15:05:16.580Z] 	at org.mockito.internal.junit.JUnitRule$1.evaluate(JUnitRule.java:48)
[2025-11-21T15:05:16.580Z] 	at org.jvnet.hudson.test.JenkinsRule$1.evaluate(JenkinsRule.java:596)
[2025-11-21T15:05:16.580Z] 	at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:298)
[2025-11-21T15:05:16.580Z] 	at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:292)
[2025-11-21T15:05:16.580Z] 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[2025-11-21T15:05:16.580Z] 	at java.lang.Thread.run(Thread.java:750)
[2025-11-21T15:05:16.581Z] 
[2025-11-21T15:05:16.581Z] [ERROR] org.jenkinsci.plugins.githubautostatus.integration.DeclarativePipelineTest.testAbort  Time elapsed: 6.612 s  <<< ERROR!
[2025-11-21T15:05:16.581Z] java.lang.NullPointerException
[2025-11-21T15:05:16.581Z] 	at org.jenkinsci.plugins.githubautostatus.integration.DeclarativePipelineTest.testAbort(DeclarativePipelineTest.java:306)
[2025-11-21T15:05:16.581Z] 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[2025-11-21T15:05:16.581Z] 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[2025-11-21T15:05:16.581Z] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[2025-11-21T15:05:16.582Z] 	at java.lang.reflect.Method.invoke(Method.java:498)
[2025-11-21T15:05:16.582Z] 	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
[2025-11-21T15:05:16.582Z] 	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
[2025-11-21T15:05:16.582Z] 	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
[2025-11-21T15:05:16.582Z] 	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
[2025-11-21T15:05:16.582Z] 	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
[2025-11-21T15:05:16.583Z] 	at org.mockito.internal.junit.JUnitRule$1.evaluateSafely(JUnitRule.java:57)
[2025-11-21T15:05:16.583Z] 	at org.mockito.internal.junit.JUnitRule$1.evaluate(JUnitRule.java:48)
[2025-11-21T15:05:16.583Z] 	at org.jvnet.hudson.test.JenkinsRule$1.evaluate(JenkinsRule.java:596)
[2025-11-21T15:05:16.583Z] 	at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:298)
[2025-11-21T15:05:16.583Z] 	at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:292)
[2025-11-21T15:05:16.583Z] 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[2025-11-21T15:05:16.583Z] 	at java.lang.Thread.run(Thread.java:750)

@jimklimov
Copy link
Author

jimklimov commented Dec 4, 2025

Stack traces due to the original issue were still seen after updating other plugins with CME concerns (lockable-resources here), but leaving this one at 3.6.2:

2025-12-03 15:03:49.019+0000 [id=111269]        WARNING o.j.p.workflow.steps.scm.SCMStep#checkout
java.util.ConcurrentModificationException
        at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1605)
        at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1638)
        at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1636)
        at com.thoughtworks.xstream.converters.collections.MapConverter.marshal(MapConverter.java:76)
        at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
        at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
        at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:83)
        at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:285)
        at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:272)
Caused: java.lang.RuntimeException: Failed to serialize org.jenkinsci.plugins.githubautostatus.BuildStatusAction#buildStatuses for class org.jenkinsci.plugins.githubautostatus.BuildStatusAction
        at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:276)
        at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:243)
        at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:174)
        at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:228)
        at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:165)
...

Now restarted that controller with a private build bypassing the tests (mvn -DskipTests package), will check how it goes in the coming weeks...

@jimklimov
Copy link
Author

jimklimov commented Dec 7, 2025

FWIW, the exception was not seen during the past week worth of builds...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant