From faa69c9b9c617b39183d1c70a42bb8c589c3f6e7 Mon Sep 17 00:00:00 2001 From: Stefan Oehme Date: Wed, 20 May 2026 23:13:18 +0200 Subject: [PATCH] Fix logging setup/teardown order (#11901) Reorder ProjectBuildLogAppender registration in LookupInvoker so that it is added to the closeables list after the terminal setup. Since closeables are closed in reverse order (LIFO), this ensures the log sink is deregistered before the terminal is torn down, preventing StackOverflowErrors during shutdown. Closes #11901 --- .../org/apache/maven/cling/invoker/LookupInvoker.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java index 5ec158321dbd..d29e09a5fc6e 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java @@ -311,11 +311,6 @@ protected BuildEventListener doDetermineBuildEventListener(C context) { protected final void createTerminal(C context) { if (context.terminal == null) { - // Create the build log appender; also sets MavenSimpleLogger sink - ProjectBuildLogAppender projectBuildLogAppender = - new ProjectBuildLogAppender(determineBuildEventListener(context)); - context.closeables.add(projectBuildLogAppender); - MessageUtils.systemInstall( builder -> doCreateTerminal(context, builder), terminal -> doConfigureWithTerminal(context, terminal)); @@ -323,6 +318,11 @@ protected final void createTerminal(C context) { context.terminal = MessageUtils.getTerminal(); context.closeables.add(MessageUtils::systemUninstall); MessageUtils.registerShutdownHook(); // safety belt + + // Create the build log appender; also sets MavenSimpleLogger sink + ProjectBuildLogAppender projectBuildLogAppender = + new ProjectBuildLogAppender(determineBuildEventListener(context)); + context.closeables.add(projectBuildLogAppender); } else { doConfigureWithTerminal(context, context.terminal); }