4747import java .util .HashMap ;
4848import java .util .Map ;
4949import java .util .Set ;
50+ import java .util .concurrent .ForkJoinPool ;
5051import java .util .concurrent .TimeUnit ;
5152import java .util .logging .Level ;
5253import java .util .logging .LogRecord ;
@@ -203,6 +204,8 @@ public class FlowExecutionListTest {
203204 }
204205
205206 @ Test public void stepExecutionIteratorDoesNotLeakBuildsWhenCpsVmIsStuck () throws Throwable {
207+ // Make sure ForkJoinPool is not initialized on a thread where its inheritedAccessControlContext would point to a CpsGroovyShell$CleanGroovyClassLoader
208+ ForkJoinPool .commonPool ().execute (() -> {});
206209 sessions .then (r -> {
207210 var notStuck = r .createProject (WorkflowJob .class , "not-stuck" );
208211 notStuck .setDefinition (new CpsFlowDefinition ("semaphore 'wait'" , true ));
@@ -220,17 +223,20 @@ public class FlowExecutionListTest {
220223 // Let notStuckBuild complete and clean up all references.
221224 SemaphoreStep .success ("wait/1" , null );
222225 r .waitForCompletion (notStuckBuild );
226+ notStuck .getLazyBuildMixIn ().removeRun (notStuckBuild );
223227 notStuckBuild = null ; // Clear out the local variable in this thread.
224228 Jenkins .get ().getQueue ().clearLeftItems (); // Otherwise we'd have to wait 5 minutes for the cache to be cleared.
225229 // Make sure that the reference can be GC'd.
226- MemoryAssert .assertGC (notStuckBuildRef , true );
230+ MemoryAssert .assertGC (notStuckBuildRef , false );
227231 // Allow stuck #1 to complete so the test can be cleaned up promptly.
228232 SynchronousBlockingStep .unblock ("stuck" );
229233 r .waitForCompletion (stuckBuild );
230234 });
231235 }
232236
233237 @ Test public void stepExecutionIteratorDoesNotLeakBuildsWhenProgramPromiseIsStuck () throws Throwable {
238+ // Make sure ForkJoinPool is not initialized on a thread where its inheritedAccessControlContext would point to a CpsGroovyShell$CleanGroovyClassLoader
239+ ForkJoinPool .commonPool ().execute (() -> {});
234240 sessions .then (r -> {
235241 var stuck = r .createProject (WorkflowJob .class , "stuck" );
236242 stuck .setDefinition (new CpsFlowDefinition (
@@ -254,10 +260,11 @@ public class FlowExecutionListTest {
254260 // Let notStuckBuild complete and clean up all references.
255261 SemaphoreStep .success ("wait/1" , null );
256262 r .waitForCompletion (notStuckBuild );
263+ notStuck .getLazyBuildMixIn ().removeRun (notStuckBuild );
257264 notStuckBuild = null ; // Clear out the local variable in this thread.
258265 Jenkins .get ().getQueue ().clearLeftItems (); // Otherwise we'd have to wait 5 minutes for the cache to be cleared.
259266 // Make sure that the reference can be GC'd.
260- MemoryAssert .assertGC (notStuckBuildRef , true );
267+ MemoryAssert .assertGC (notStuckBuildRef , false );
261268 // Allow stuck #1 to complete so the test can be cleaned up promptly.
262269 r .waitForMessage ("Still trying to load StuckPickle for" , stuckBuild );
263270 ExtensionList .lookupSingleton (StuckPickle .Factory .class ).resolved = new StuckPickle .Marker ();
0 commit comments