{"record":{"id":"ed95cd8f45ac5911","repo":"junit-team/junit5","slug":"launcher-session-has-already-been-closed","errorCode":null,"errorMessage":"Launcher session has already been closed","messagePattern":"Launcher session has already been closed","errorType":"validation","errorClass":"PreconditionViolationException","httpStatus":null,"severity":"error","filePath":"junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/DefaultLauncherSession.java","lineNumber":109,"sourceCode":"\t\t\tinterceptor.close();\n\t\t}\n\t}\n\n\t@Override\n\tpublic NamespacedHierarchicalStore<Namespace> getStore() {\n\t\treturn store;\n\t}\n\n\tprivate static class ClosedLauncher implements Launcher {\n\n\t\tstatic final ClosedLauncher INSTANCE = new ClosedLauncher();\n\n\t\tprivate ClosedLauncher() {\n\t\t}\n\n\t\t@Override\n\t\tpublic void registerLauncherDiscoveryListeners(LauncherDiscoveryListener... listeners) {\n\t\t\tthrow new PreconditionViolationException(\"Launcher session has already been closed\");\n\t\t}\n\n\t\t@Override\n\t\tpublic void registerTestExecutionListeners(TestExecutionListener... listeners) {\n\t\t\tthrow new PreconditionViolationException(\"Launcher session has already been closed\");\n\t\t}\n\n\t\t@Override\n\t\tpublic TestPlan discover(LauncherDiscoveryRequest launcherDiscoveryRequest) {\n\t\t\tthrow new PreconditionViolationException(\"Launcher session has already been closed\");\n\t\t}\n\n\t\t@Override\n\t\tpublic void execute(LauncherDiscoveryRequest launcherDiscoveryRequest, TestExecutionListener... listeners) {\n\t\t\tthrow new PreconditionViolationException(\"Launcher session has already been closed\");\n\t\t}\n\n\t\t@Override","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/DefaultLauncherSession.java#L91-L127","documentation":"After LauncherSession.close(), the session swaps its Launcher for a ClosedLauncher singleton whose registerLauncherDiscoveryListeners(...) unconditionally throws PreconditionViolationException. Any attempt to register a discovery listener on a closed session is rejected.","triggerScenarios":"Calling launcher.registerLauncherDiscoveryListeners(...) on the Launcher obtained from a LauncherSession that has already been closed (session.close() ran, or the try-with-resources block exited).","commonSituations":"Try-with-resources on LauncherSessionFactory.openSession() where listener registration happens after the block; a long-lived holder that captures the Launcher and uses it after the session closes; a plugin/tool that opens a session, closes it, then registers listeners.","solutions":["Register listeners before closing the session, inside the session's lifetime (within the try-with-resources block).","If you need a fresh session, open a new one via LauncherSessionFactory.openSession() and register on its Launcher.","Track session state in your code and skip registration (or reopen) once closed."],"exampleFix":"// before\ntry (var session = factory.openSession()) {\n    Launcher l = session.getLauncher();\n} // session closed\nl.registerLauncherDiscoveryListeners(listener); // throws\n// after\ntry (var session = factory.openSession()) {\n    Launcher l = session.getLauncher();\n    l.registerLauncherDiscoveryListeners(listener); // in scope\n}","handlingStrategy":"validation","validationCode":"// Ensure listener registration happens before closing the session\ntry (var session = factory.openSession()) {\n    Launcher l = session.getLauncher();\n    l.registerLauncherDiscoveryListeners(listener); // in scope\n}","typeGuard":null,"tryCatchPattern":"try {\n    launcher.registerLauncherDiscoveryListeners(listener);\n} catch (PreconditionViolationException e) {\n    // session closed: open a new session and retry\n}","preventionTips":["Register all listeners inside the session try-with-resources block.","Do not call launcher methods after session.close().","Open a fresh session per independent run."],"tags":["launcher","session-closed","listener","precondition"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}