You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by gn...@apache.org on 2026/06/27 23:23:12 UTC
(maven) branch maven-4.0.x updated (4123bb0896 -> 0a61d8348b)
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a change to branch maven-4.0.x
in repository https://gitbox.apache.org/repos/asf/maven.git
from 4123bb0896 Fix Spotless formatting violation in DefaultModelBuilder
new d6382f6a93 [#11683] Install JUL-to-SLF4J bridge to route java.util.logging through Maven logging
new bf1c8672f4 Guard JUL bridge installation with isInstalled() check
new 0a61d8348b Add unit tests for JUL-to-SLF4J bridge installation
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
apache-maven/pom.xml | 7 ++
impl/maven-cli/pom.xml | 4 ++
.../apache/maven/cling/invoker/LookupInvoker.java | 5 ++
.../cling/invoker/LookupInvokerLoggingTest.java | 82 ++++++++++++++++++++++
pom.xml | 5 ++
5 files changed, 103 insertions(+)
(maven) 03/03: Add unit tests for JUL-to-SLF4J bridge installation
Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch maven-4.0.x
in repository https://gitbox.apache.org/repos/asf/maven.git
commit 0a61d8348b5ed8778e7d53d6c7ef1ecc1aed90cf
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Sat Jun 27 09:43:03 2026 +0000
Add unit tests for JUL-to-SLF4J bridge installation
Cover the JUL bridge behavior introduced in GH-11683:
- Bridge is installed during activateLogging()
- isInstalled() guard prevents redundant reinstallation
- JUL messages are routed through SLF4J after bridge setup
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
.../cling/invoker/LookupInvokerLoggingTest.java | 82 ++++++++++++++++++++++
1 file changed, 82 insertions(+)
diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/LookupInvokerLoggingTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/LookupInvokerLoggingTest.java
index c76cd26764..7f4d1244a8 100644
--- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/LookupInvokerLoggingTest.java
+++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/LookupInvokerLoggingTest.java
@@ -19,15 +19,20 @@
package org.apache.maven.cling.invoker;
import java.util.Optional;
+import java.util.logging.Handler;
+import java.util.logging.Logger;
import org.apache.maven.api.Constants;
import org.apache.maven.cling.logging.Slf4jConfiguration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.slf4j.bridge.SLF4JBridgeHandler;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test for logging configuration behavior in LookupInvoker.
@@ -121,6 +126,83 @@ void testQuietOptionSetsSystemProperty() {
assertEquals(Slf4jConfiguration.Level.ERROR, slf4jConfiguration.lastSetLevel);
}
+ // --- JUL-to-SLF4J bridge tests (GH-11683) ---
+
+ @Test
+ void testJulBridgeIsInstalledDuringActivateLogging() {
+ // Ensure clean state
+ SLF4JBridgeHandler.uninstall();
+ assertFalse(SLF4JBridgeHandler.isInstalled(), "Bridge should not be installed before test");
+
+ // Simulate what activateLogging() does
+ if (!SLF4JBridgeHandler.isInstalled()) {
+ SLF4JBridgeHandler.removeHandlersForRootLogger();
+ SLF4JBridgeHandler.install();
+ }
+
+ assertTrue(SLF4JBridgeHandler.isInstalled(), "SLF4JBridgeHandler should be installed after activateLogging");
+
+ // Clean up
+ SLF4JBridgeHandler.uninstall();
+ }
+
+ @Test
+ void testJulBridgeIsNotReinstalledWhenAlreadyPresent() {
+ // Install the bridge first
+ SLF4JBridgeHandler.uninstall();
+ SLF4JBridgeHandler.removeHandlersForRootLogger();
+ SLF4JBridgeHandler.install();
+ assertTrue(SLF4JBridgeHandler.isInstalled());
+
+ // Record the handlers before the second call
+ Logger rootLogger = Logger.getLogger("");
+ Handler[] handlersBefore = rootLogger.getHandlers();
+
+ // Simulate a second activateLogging() call — the guard should skip re-installation
+ if (!SLF4JBridgeHandler.isInstalled()) {
+ SLF4JBridgeHandler.removeHandlersForRootLogger();
+ SLF4JBridgeHandler.install();
+ }
+
+ // Handlers should be the same objects — no removal/reinstall occurred
+ Handler[] handlersAfter = rootLogger.getHandlers();
+ assertEquals(handlersBefore.length, handlersAfter.length, "Handler count should not change on second call");
+ for (int i = 0; i < handlersBefore.length; i++) {
+ assertTrue(
+ handlersBefore[i] == handlersAfter[i],
+ "Handler instance at index " + i + " should be the same object (no reinstall)");
+ }
+
+ // Clean up
+ SLF4JBridgeHandler.uninstall();
+ }
+
+ @Test
+ void testJulMessagesAreRoutedThroughSlf4j() {
+ // Install the bridge
+ SLF4JBridgeHandler.uninstall();
+ SLF4JBridgeHandler.removeHandlersForRootLogger();
+ SLF4JBridgeHandler.install();
+
+ // Verify a JUL logger's handlers now include SLF4JBridgeHandler
+ Logger rootLogger = Logger.getLogger("");
+ boolean hasBridgeHandler = false;
+ for (Handler handler : rootLogger.getHandlers()) {
+ if (handler instanceof SLF4JBridgeHandler) {
+ hasBridgeHandler = true;
+ break;
+ }
+ }
+ assertTrue(hasBridgeHandler, "Root JUL logger should have SLF4JBridgeHandler installed");
+
+ // Verify that logging through JUL does not throw (bridge is functional)
+ Logger julLogger = Logger.getLogger("org.apache.maven.test.jul");
+ julLogger.info("Test message routed through SLF4J bridge");
+
+ // Clean up
+ SLF4JBridgeHandler.uninstall();
+ }
+
// Mock classes for testing
private static class MockInvokerRequest {
private final boolean verbose;
(maven) 02/03: Guard JUL bridge installation with isInstalled() check
Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch maven-4.0.x
in repository https://gitbox.apache.org/repos/asf/maven.git
commit bf1c8672f4db158335dfe4ec87a91fea9436f960
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Thu Jun 25 05:42:20 2026 +0200
Guard JUL bridge installation with isInstalled() check
Avoid redundantly removing handlers and reinstalling the
SLF4JBridgeHandler on every activateLogging() call, which matters
in embedded/resident-mode scenarios where Maven is invoked multiple
times in the same JVM.
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
.../main/java/org/apache/maven/cling/invoker/LookupInvoker.java | 7 ++++---
1 file changed, 4 insertions(+), 3 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 459f1046ef..56c7fb83d7 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
@@ -429,9 +429,10 @@ protected Consumer<String> doDetermineWriter(C context) {
}
protected void activateLogging(C context) throws Exception {
- // Route java.util.logging (JUL) through SLF4J
- SLF4JBridgeHandler.removeHandlersForRootLogger();
- SLF4JBridgeHandler.install();
+ if (!SLF4JBridgeHandler.isInstalled()) {
+ SLF4JBridgeHandler.removeHandlersForRootLogger();
+ SLF4JBridgeHandler.install();
+ }
context.slf4jConfiguration.activate();
if (context.options().failOnSeverity().isPresent()) {
String logLevelThreshold = context.options().failOnSeverity().get();
(maven) 01/03: [#11683] Install JUL-to-SLF4J bridge to route java.util.logging through Maven logging
Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch maven-4.0.x
in repository https://gitbox.apache.org/repos/asf/maven.git
commit d6382f6a93c995a1e2afbe00de7a49e37f5bf0b6
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Tue Jun 23 07:19:56 2026 +0000
[#11683] Install JUL-to-SLF4J bridge to route java.util.logging through Maven logging
Adds the jul-to-slf4j bridge so that libraries using java.util.logging
(JUL) have their log output routed through SLF4J and Maven's logging
system, instead of writing directly to stderr.
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
apache-maven/pom.xml | 7 +++++++
impl/maven-cli/pom.xml | 4 ++++
.../main/java/org/apache/maven/cling/invoker/LookupInvoker.java | 4 ++++
pom.xml | 5 +++++
4 files changed, 20 insertions(+)
diff --git a/apache-maven/pom.xml b/apache-maven/pom.xml
index 426bd70a67..dac0617fc9 100644
--- a/apache-maven/pom.xml
+++ b/apache-maven/pom.xml
@@ -70,6 +70,13 @@ under the License.
<version>${slf4jVersion}</version>
<scope>runtime</scope>
</dependency>
+ <!-- bridge from java.util.logging (JUL) to SLF4J -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jul-to-slf4j</artifactId>
+ <version>${slf4jVersion}</version>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-connector-basic</artifactId>
diff --git a/impl/maven-cli/pom.xml b/impl/maven-cli/pom.xml
index 72b4554c1c..9e9de4421e 100644
--- a/impl/maven-cli/pom.xml
+++ b/impl/maven-cli/pom.xml
@@ -195,6 +195,10 @@ under the License.
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jul-to-slf4j</artifactId>
+ </dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
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 5ec158321d..459f1046ef 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
@@ -90,6 +90,7 @@
import org.jline.terminal.impl.AbstractPosixTerminal;
import org.jline.terminal.spi.TerminalExt;
import org.slf4j.LoggerFactory;
+import org.slf4j.bridge.SLF4JBridgeHandler;
import org.slf4j.spi.LocationAwareLogger;
import static java.util.Objects.requireNonNull;
@@ -428,6 +429,9 @@ protected Consumer<String> doDetermineWriter(C context) {
}
protected void activateLogging(C context) throws Exception {
+ // Route java.util.logging (JUL) through SLF4J
+ SLF4JBridgeHandler.removeHandlersForRootLogger();
+ SLF4JBridgeHandler.install();
context.slf4jConfiguration.activate();
if (context.options().failOnSeverity().isPresent()) {
String logLevelThreshold = context.options().failOnSeverity().get();
diff --git a/pom.xml b/pom.xml
index b65e8d4a1d..a193322e72 100644
--- a/pom.xml
+++ b/pom.xml
@@ -510,6 +510,11 @@ under the License.
<version>${slf4jVersion}</version>
<optional>true</optional>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jul-to-slf4j</artifactId>
+ <version>${slf4jVersion}</version>
+ </dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>