diff --git a/client/pom.xml b/client/pom.xml
index dfb357b2c..0cbd3b29c 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -43,12 +43,12 @@
mvnd-common
- org.apache.maven
- maven-embedder
+ org.apache.maven.daemon
+ mvnd-logging
- org.slf4j
- slf4j-simple
+ org.apache.maven
+ maven-embedder
org.slf4j
diff --git a/client/src/main/java-fallback/org/mvndaemon/mvnd/client/DefaultClient.java b/client/src/main/java-fallback/org/mvndaemon/mvnd/client/DefaultClient.java
index ddc55b562..0dd015853 100644
--- a/client/src/main/java-fallback/org/mvndaemon/mvnd/client/DefaultClient.java
+++ b/client/src/main/java-fallback/org/mvndaemon/mvnd/client/DefaultClient.java
@@ -24,12 +24,6 @@
public class DefaultClient {
public static void main(String[] argv) throws Exception {
- final String logbackConfFallback = System.getProperty("logback.configurationFile.fallback");
- if (null != logbackConfFallback && !"".equals(logbackConfFallback)) {
- System.setProperty("logback.configurationFile", logbackConfFallback);
- System.clearProperty("logback.configurationFile.fallback");
- }
-
final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class);
LOGGER.warn("Found old JDK, fallback to the embedded maven!");
LOGGER.warn("Use JDK 11+ to run maven-mvnd client!");
diff --git a/client/src/main/java-mvnd/org/mvndaemon/mvnd/client/DefaultClient.java b/client/src/main/java-mvnd/org/mvndaemon/mvnd/client/DefaultClient.java
index dd010ff3a..ee5f9ae09 100644
--- a/client/src/main/java-mvnd/org/mvndaemon/mvnd/client/DefaultClient.java
+++ b/client/src/main/java-mvnd/org/mvndaemon/mvnd/client/DefaultClient.java
@@ -60,6 +60,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.bridge.SLF4JBridgeHandler;
+import org.slf4j.impl.MvndLoggerFactory;
+import org.slf4j.impl.StaticLoggerBinder;
import static org.mvndaemon.mvnd.client.DaemonParameters.LOG_EXTENSION;
@@ -70,8 +72,6 @@ public class DefaultClient implements Client {
private final DaemonParameters parameters;
public static void main(String[] argv) throws Exception {
- System.clearProperty("logback.configurationFile.fallback");
-
final List args = new ArrayList<>(Arrays.asList(argv));
// Log file
@@ -115,6 +115,10 @@ public static void main(String[] argv) throws Exception {
// System properties
setSystemPropertiesFromCommandLine(args);
+ if (StaticLoggerBinder.getSingleton().getLoggerFactory() instanceof MvndLoggerFactory) {
+ ((MvndLoggerFactory) StaticLoggerBinder.getSingleton().getLoggerFactory()).reconfigure();
+ }
+
DaemonParameters parameters = new DaemonParameters();
if (parameters.serial()) {
System.setProperty(Environment.MVND_THREADS.getProperty(), Integer.toString(1));
@@ -191,9 +195,13 @@ public static void setSystemPropertiesFromCommandLine(List args) {
/* This needs to be done very early, otherwise various DaemonParameters do not work properly */
final int eqPos = val.indexOf('=');
if (eqPos >= 0) {
- System.setProperty(val.substring(0, eqPos), val.substring(eqPos + 1));
+ String k = val.substring(0, eqPos);
+ String v = val.substring(eqPos + 1);
+ System.setProperty(k, v);
+ LOGGER.trace("Setting system property {} to {}", k, v);
} else {
System.setProperty(val, "");
+ LOGGER.trace("Setting system property {}", val);
}
}
}
diff --git a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonConnector.java b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonConnector.java
index 537f0bbba..912a05e92 100644
--- a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonConnector.java
+++ b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonConnector.java
@@ -57,6 +57,7 @@
import org.mvndaemon.mvnd.common.logging.ClientOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.slf4j.impl.SimpleLogger;
import static java.lang.Thread.sleep;
import static org.mvndaemon.mvnd.common.DaemonState.Canceled;
@@ -433,10 +434,11 @@ private Process startDaemonProcess(String daemonId, ClientOutput output) {
args.add("-Dmaven.conf=" + mvndHome.resolve("mvn").resolve("conf"));
args.add("-Dclassworlds.conf=" + mvndHome.resolve("bin").resolve("mvnd-daemon.conf"));
+ args.add("-D" + SimpleLogger.LOG_FILE_KEY + "="
+ + parameters.daemonStorage().resolve("daemon-" + daemonId + ".log"));
+
Environment.MVND_JAVA_HOME.addSystemProperty(
args, parameters.javaHome().toString());
- Environment.LOGBACK_CONFIGURATION_FILE.addSystemProperty(
- args, parameters.logbackConfigurationPath().toString());
Environment.MVND_ID.addSystemProperty(args, daemonId);
Environment.MVND_DAEMON_STORAGE.addSystemProperty(
args, parameters.daemonStorage().toString());
diff --git a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java
index c0230f891..d14f3e41c 100644
--- a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java
+++ b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java
@@ -184,11 +184,21 @@ private static String javaHomeFromPath() {
}
public Path userDir() {
- return value(Environment.USER_DIR).orSystemProperty().orFail().asPath().toAbsolutePath();
+ return value(Environment.USER_DIR)
+ .orSystemProperty()
+ .orFail()
+ .cache(provider)
+ .asPath()
+ .toAbsolutePath();
}
public Path userHome() {
- return value(Environment.USER_HOME).orSystemProperty().orFail().asPath().toAbsolutePath();
+ return value(Environment.USER_HOME)
+ .orSystemProperty()
+ .orFail()
+ .cache(provider)
+ .asPath()
+ .toAbsolutePath();
}
public Path suppliedPropertiesPath() {
@@ -256,15 +266,6 @@ public Path multiModuleProjectDirectory(Path projectDir) {
.normalize();
}
- public Path logbackConfigurationPath() {
- return property(Environment.MVND_LOGBACK)
- .orDefault(() -> mvndHome()
- .resolve("mvn/conf/logging/logback-daemon.xml")
- .toString())
- .orFail()
- .asPath();
- }
-
public String minHeapSize() {
return property(Environment.MVND_MIN_HEAP_SIZE).asString();
}
diff --git a/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java b/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java
index c0892f741..ac0e9a6c5 100644
--- a/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java
+++ b/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java
@@ -62,17 +62,6 @@ public enum Environment {
/** Use one thread, no log buffering and the default project builder to behave like a standard maven */
SERIAL("mvnd.serial", null, Boolean.FALSE, OptionType.VOID, Flags.OPTIONAL, "mvnd:-1", "mvnd:--serial"),
- //
- // Log properties
- //
-
- /**
- * The location of the Logback configuration file the daemon should use to configure its logging.
- */
- MVND_LOGBACK("mvnd.logback", null, null, OptionType.PATH, Flags.NONE),
- /** The system property expected by logback to set the configuration file */
- LOGBACK_CONFIGURATION_FILE("logback.configurationFile", null, null, OptionType.PATH, Flags.INTERNAL),
-
//
// System properties
//
diff --git a/daemon-m39/src/main/java/org/apache/maven/cli/DaemonMavenCli.java b/daemon-m39/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
index 7ddc25157..53301faa3 100644
--- a/daemon-m39/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
+++ b/daemon-m39/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
@@ -57,6 +57,8 @@
import org.apache.maven.cli.event.ExecutionEventLogger;
import org.apache.maven.cli.internal.BootstrapCoreExtensionManager;
import org.apache.maven.cli.internal.extension.model.CoreExtension;
+import org.apache.maven.cli.logging.Slf4jConfiguration;
+import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
import org.apache.maven.cli.transfer.QuietMavenTransferListener;
import org.apache.maven.cli.transfer.Slf4jMavenTransferListener;
import org.apache.maven.eventspy.internal.EventSpyDispatcher;
@@ -113,6 +115,8 @@
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.slf4j.impl.MvndSimpleLogger;
+import org.slf4j.spi.LocationAwareLogger;
import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
@@ -365,15 +369,17 @@ void logging(CliRequest cliRequest) {
cliRequest.quiet = !cliRequest.debug && cliRequest.commandLine.hasOption(CLIManager.QUIET);
cliRequest.showErrors = cliRequest.debug || cliRequest.commandLine.hasOption(CLIManager.ERRORS);
- ch.qos.logback.classic.Level level;
+ Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration(slf4jLoggerFactory);
+
if (cliRequest.debug) {
- level = ch.qos.logback.classic.Level.DEBUG;
+ cliRequest.request.setLoggingLevel(MavenExecutionRequest.LOGGING_LEVEL_DEBUG);
+ slf4jConfiguration.setRootLoggerLevel(Slf4jConfiguration.Level.DEBUG);
} else if (cliRequest.quiet) {
- level = ch.qos.logback.classic.Level.WARN;
- } else {
- level = ch.qos.logback.classic.Level.INFO;
+ cliRequest.request.setLoggingLevel(MavenExecutionRequest.LOGGING_LEVEL_ERROR);
+ slf4jConfiguration.setRootLoggerLevel(Slf4jConfiguration.Level.ERROR);
}
- ((ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)).setLevel(level);
+ // else fall back to default log level specified in conf
+ // see https://issues.apache.org/jira/browse/MNG-2570
// LOG COLOR
String styleColor = cliRequest.getUserProperties().getProperty(STYLE_COLOR_PROPERTY, "auto");
@@ -389,11 +395,6 @@ void logging(CliRequest cliRequest) {
MessageUtils.setColorEnabled(false);
}
- // Workaround for https://github.com/apache/maven-mvnd/issues/39
- final ch.qos.logback.classic.Logger mvndLogger =
- (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("org.mvndaemon.mvnd");
- mvndLogger.setLevel(ch.qos.logback.classic.Level.toLevel(System.getProperty("mvnd.log.level"), null));
-
// LOG STREAMS
if (cliRequest.commandLine.hasOption(CLIManager.LOG_FILE)) {
File logFile = new File(cliRequest.commandLine.getOptionValue(CLIManager.LOG_FILE));
@@ -413,15 +414,15 @@ void logging(CliRequest cliRequest) {
.asOptional()
.map(Boolean::parseBoolean)
.orElse(Boolean.FALSE)) {
- ch.qos.logback.classic.Logger stdout =
- (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("stdout");
- ch.qos.logback.classic.Logger stderr =
- (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("stderr");
- stdout.setLevel(ch.qos.logback.classic.Level.INFO);
- stderr.setLevel(ch.qos.logback.classic.Level.INFO);
+ MvndSimpleLogger stdout = (MvndSimpleLogger) slf4jLoggerFactory.getLogger("stdout");
+ MvndSimpleLogger stderr = (MvndSimpleLogger) slf4jLoggerFactory.getLogger("stderr");
+ stdout.setLogLevel(LocationAwareLogger.INFO_INT);
+ stderr.setLogLevel(LocationAwareLogger.INFO_INT);
System.setOut(new LoggingOutputStream(s -> stdout.info("[stdout] " + s)).printStream());
System.setErr(new LoggingOutputStream(s -> stderr.warn("[stderr] " + s)).printStream());
}
+
+ slf4jConfiguration.activate();
}
private void version(CliRequest cliRequest) throws ExitException {
diff --git a/daemon-m40/src/main/java/org/apache/maven/cli/DaemonMavenCli.java b/daemon-m40/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
index d83324e03..96ec7b877 100644
--- a/daemon-m40/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
+++ b/daemon-m40/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
@@ -54,6 +54,8 @@
import org.apache.maven.cli.internal.extension.model.CoreExtension;
import org.apache.maven.cli.jansi.JansiMessageBuilderFactory;
import org.apache.maven.cli.jansi.MessageUtils;
+import org.apache.maven.cli.logging.Slf4jConfiguration;
+import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
import org.apache.maven.cli.transfer.QuietMavenTransferListener;
import org.apache.maven.cli.transfer.Slf4jMavenTransferListener;
import org.apache.maven.eventspy.internal.EventSpyDispatcher;
@@ -103,6 +105,8 @@
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.slf4j.impl.MvndSimpleLogger;
+import org.slf4j.spi.LocationAwareLogger;
import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
@@ -411,15 +415,17 @@ void logging(CliRequest cliRequest) {
cliRequest.quiet = !cliRequest.verbose && commandLine.hasOption(CLIManager.QUIET);
cliRequest.showErrors = cliRequest.verbose || commandLine.hasOption(CLIManager.ERRORS);
- ch.qos.logback.classic.Level level;
+ Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration(slf4jLoggerFactory);
+
if (cliRequest.verbose) {
- level = ch.qos.logback.classic.Level.DEBUG;
+ cliRequest.request.setLoggingLevel(MavenExecutionRequest.LOGGING_LEVEL_DEBUG);
+ slf4jConfiguration.setRootLoggerLevel(Slf4jConfiguration.Level.DEBUG);
} else if (cliRequest.quiet) {
- level = ch.qos.logback.classic.Level.WARN;
- } else {
- level = ch.qos.logback.classic.Level.INFO;
+ cliRequest.request.setLoggingLevel(MavenExecutionRequest.LOGGING_LEVEL_ERROR);
+ slf4jConfiguration.setRootLoggerLevel(Slf4jConfiguration.Level.ERROR);
}
- ((ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)).setLevel(level);
+ // else fall back to default log level specified in conf
+ // see https://issues.apache.org/jira/browse/MNG-2570
// LOG COLOR
String styleColor = cliRequest.getUserProperties().getProperty(STYLE_COLOR_PROPERTY, "auto");
@@ -438,11 +444,6 @@ void logging(CliRequest cliRequest) {
}
}
- // Workaround for https://github.com/apache/maven-mvnd/issues/39
- final ch.qos.logback.classic.Logger mvndLogger =
- (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("org.mvndaemon.mvnd");
- mvndLogger.setLevel(ch.qos.logback.classic.Level.toLevel(System.getProperty("mvnd.log.level"), null));
-
// LOG STREAMS
if (commandLine.hasOption(CLIManager.LOG_FILE)) {
File logFile = new File(commandLine.getOptionValue(CLIManager.LOG_FILE));
@@ -462,15 +463,15 @@ void logging(CliRequest cliRequest) {
.asOptional()
.map(Boolean::parseBoolean)
.orElse(Boolean.FALSE)) {
- ch.qos.logback.classic.Logger stdout =
- (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("stdout");
- ch.qos.logback.classic.Logger stderr =
- (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("stderr");
- stdout.setLevel(ch.qos.logback.classic.Level.INFO);
- stderr.setLevel(ch.qos.logback.classic.Level.INFO);
+ MvndSimpleLogger stdout = (MvndSimpleLogger) slf4jLoggerFactory.getLogger("stdout");
+ MvndSimpleLogger stderr = (MvndSimpleLogger) slf4jLoggerFactory.getLogger("stderr");
+ stdout.setLogLevel(LocationAwareLogger.INFO_INT);
+ stderr.setLogLevel(LocationAwareLogger.INFO_INT);
System.setOut(new LoggingOutputStream(s -> stdout.info("[stdout] " + s)).printStream());
System.setErr(new LoggingOutputStream(s -> stderr.warn("[stderr] " + s)).printStream());
}
+
+ slf4jConfiguration.activate();
}
private void version(CliRequest cliRequest) throws ExitException {
diff --git a/daemon/pom.xml b/daemon/pom.xml
index 5acd3fb0e..aee12fac3 100644
--- a/daemon/pom.xml
+++ b/daemon/pom.xml
@@ -64,10 +64,6 @@
-
- ch.qos.logback
- logback-classic
-
org.slf4j
log4j-over-slf4j
diff --git a/daemon/src/main/resources/META-INF/maven/slf4j-configuration.properties b/daemon/src/main/resources/META-INF/maven/slf4j-configuration.properties
deleted file mode 100644
index 69dc8b64a..000000000
--- a/daemon/src/main/resources/META-INF/maven/slf4j-configuration.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright 2019 the original author or authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# key = Slf4j effective logger factory implementation
-# value = corresponding o.a.m.cli.logging.Slf4jConfiguration class
-ch.qos.logback.classic.LoggerContext org.mvndaemon.mvnd.logging.internal.MvndSlf4jConfiguration
diff --git a/dist-m39/src/main/provisio/maven-distro.xml b/dist-m39/src/main/provisio/maven-distro.xml
index f2b2759c7..caa8d6edc 100644
--- a/dist-m39/src/main/provisio/maven-distro.xml
+++ b/dist-m39/src/main/provisio/maven-distro.xml
@@ -20,7 +20,7 @@
+ excludes="lib/maven-slf4j-*" />
@@ -28,12 +28,6 @@
-
-
-
-
-
-
diff --git a/dist-m40/src/main/provisio/maven-distro.xml b/dist-m40/src/main/provisio/maven-distro.xml
index d3ec052a5..0faf498f3 100644
--- a/dist-m40/src/main/provisio/maven-distro.xml
+++ b/dist-m40/src/main/provisio/maven-distro.xml
@@ -20,7 +20,7 @@
+ excludes="lib/maven-slf4j-*,lib/plexus-utils-3.*" />
@@ -28,12 +28,6 @@
-
-
-
-
-
-
diff --git a/dist/src/main/distro/bin/mvnd-bash-completion.bash b/dist/src/main/distro/bin/mvnd-bash-completion.bash
index 0dde19ffd..473eca900 100755
--- a/dist/src/main/distro/bin/mvnd-bash-completion.bash
+++ b/dist/src/main/distro/bin/mvnd-bash-completion.bash
@@ -218,7 +218,7 @@ _mvnd()
local mvnd_opts="-1"
local mvnd_long_opts="--color|--completion|--purge|--raw-streams|--serial|--status|--stop"
- local mvnd_properties="-Djava.home|-Djdk.java.options|-Dmaven.multiModuleProjectDirectory|-Dmaven.repo.local|-Dmaven.settings|-Dmvnd.buildTime|-Dmvnd.builder|-Dmvnd.cancelConnectTimeout|-Dmvnd.connectTimeout|-Dmvnd.daemonStorage|-Dmvnd.debug|-Dmvnd.debug.address|-Dmvnd.duplicateDaemonGracePeriod|-Dmvnd.enableAssertions|-Dmvnd.expirationCheckDelay|-Dmvnd.home|-Dmvnd.idleTimeout|-Dmvnd.jvmArgs|-Dmvnd.keepAlive|-Dmvnd.logPurgePeriod|-Dmvnd.logback|-Dmvnd.maxHeapSize|-Dmvnd.maxLostKeepAlive|-Dmvnd.minHeapSize|-Dmvnd.minThreads|-Dmvnd.noBuffering|-Dmvnd.noDaemon|-Dmvnd.noModelCache|-Dmvnd.pluginRealmEvictPattern|-Dmvnd.propertiesPath|-Dmvnd.rawStreams|-Dmvnd.registry|-Dmvnd.rollingWindowSize|-Dmvnd.serial|-Dmvnd.socketConnectTimeout|-Dmvnd.socketFamily|-Dmvnd.threadStackSize|-Dmvnd.threads|-Dstyle.color|-Duser.dir|-Duser.home"
+ local mvnd_properties="-Djava.home|-Djdk.java.options|-Dmaven.multiModuleProjectDirectory|-Dmaven.repo.local|-Dmaven.settings|-Dmvnd.buildTime|-Dmvnd.builder|-Dmvnd.cancelConnectTimeout|-Dmvnd.connectTimeout|-Dmvnd.daemonStorage|-Dmvnd.debug|-Dmvnd.debug.address|-Dmvnd.duplicateDaemonGracePeriod|-Dmvnd.enableAssertions|-Dmvnd.expirationCheckDelay|-Dmvnd.home|-Dmvnd.idleTimeout|-Dmvnd.jvmArgs|-Dmvnd.keepAlive|-Dmvnd.logPurgePeriod|-Dmvnd.maxHeapSize|-Dmvnd.maxLostKeepAlive|-Dmvnd.minHeapSize|-Dmvnd.minThreads|-Dmvnd.noBuffering|-Dmvnd.noDaemon|-Dmvnd.noModelCache|-Dmvnd.pluginRealmEvictPattern|-Dmvnd.propertiesPath|-Dmvnd.rawStreams|-Dmvnd.registry|-Dmvnd.rollingWindowSize|-Dmvnd.serial|-Dmvnd.socketConnectTimeout|-Dmvnd.socketFamily|-Dmvnd.threadStackSize|-Dmvnd.threads|-Dstyle.color|-Duser.dir|-Duser.home"
local opts="-am|-amd|-B|-C|-c|-cpu|-D|-e|-emp|-ep|-f|-fae|-ff|-fn|-gs|-h|-l|-N|-npr|-npu|-nsu|-o|-P|-pl|-q|-rf|-s|-T|-t|-U|-up|-V|-v|-X|${mvnd_opts}"
local long_opts="--also-make|--also-make-dependents|--batch-mode|--strict-checksums|--lax-checksums|--check-plugin-updates|--define|--errors|--encrypt-master-password|--encrypt-password|--file|--fail-at-end|--fail-fast|--fail-never|--global-settings|--help|--log-file|--non-recursive|--no-plugin-registry|--no-plugin-updates|--no-snapshot-updates|--offline|--activate-profiles|--projects|--quiet|--resume-from|--settings|--threads|--toolchains|--update-snapshots|--update-plugins|--show-version|--version|--debug|${mvnd_long_opts}"
diff --git a/dist/src/main/distro/bin/mvnd-client.conf b/dist/src/main/distro/bin/mvnd-client.conf
index ed682f0b8..0b6487777 100644
--- a/dist/src/main/distro/bin/mvnd-client.conf
+++ b/dist/src/main/distro/bin/mvnd-client.conf
@@ -20,8 +20,6 @@ set maven.home default ${mvnd.home}/mvn
set maven.conf default ${maven.home}/conf
set java.util.logging.config.file default ${maven.conf}/logging/java.util.logging.properties
-set logback.configurationFile default ${maven.conf}/logging/logback-client.xml
-set logback.configurationFile.fallback default ${maven.conf}/logging/logback.xml
[plexus.core]
load ${maven.conf}/logging
diff --git a/dist/src/main/distro/bin/mvnd-daemon.conf b/dist/src/main/distro/bin/mvnd-daemon.conf
index b387bd2df..7a2b40b5e 100644
--- a/dist/src/main/distro/bin/mvnd-daemon.conf
+++ b/dist/src/main/distro/bin/mvnd-daemon.conf
@@ -20,8 +20,6 @@ set maven.home default ${mvnd.home}/mvn
set maven.conf default ${maven.home}/conf
set java.util.logging.config.file default ${maven.conf}/logging/java.util.logging.properties
-set logback.configurationFile default ${maven.conf}/logging/logback-daemon.xml
-set logback.configurationFile.fallback default ${maven.conf}/logging/logback.xml
[plexus.core]
load ${maven.conf}/logging
diff --git a/dist/src/main/distro/mvn/conf/logging/logback-client.xml b/dist/src/main/distro/mvn/conf/logging/logback-client.xml
deleted file mode 100644
index abadf029d..000000000
--- a/dist/src/main/distro/mvn/conf/logging/logback-client.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
- %-5relative %-5level %logger{35} - %msg%n
-
-
-
-
-
-
-
diff --git a/dist/src/main/distro/mvn/conf/logging/logback-daemon.xml b/dist/src/main/distro/mvn/conf/logging/logback-daemon.xml
deleted file mode 100644
index 97a6053be..000000000
--- a/dist/src/main/distro/mvn/conf/logging/logback-daemon.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
- ${mvnd.daemonStorage}/daemon-${mvnd.id}.log
-
- %d{HH:mm:ss.SSS} %.-1level %msg%n
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/dist/src/main/distro/mvn/conf/logging/logback.xml b/dist/src/main/distro/mvn/conf/logging/logback.xml
deleted file mode 100644
index 1628306d0..000000000
--- a/dist/src/main/distro/mvn/conf/logging/logback.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MaxHeapNativeIT.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MaxHeapNativeIT.java
index 2b00562fe..4e0173b57 100644
--- a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MaxHeapNativeIT.java
+++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MaxHeapNativeIT.java
@@ -20,10 +20,9 @@
import javax.inject.Inject;
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.read.ListAppender;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
@@ -32,6 +31,8 @@
import org.mvndaemon.mvnd.client.Client;
import org.mvndaemon.mvnd.junit.MvndNativeTest;
import org.slf4j.LoggerFactory;
+import org.slf4j.impl.MvndSimpleLogger;
+import org.slf4j.spi.LocationAwareLogger;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -42,33 +43,31 @@ static class BaseTest {
@Inject
Client client;
- static ListAppender appender = new ListAppender<>();
+ static List messages = new CopyOnWriteArrayList<>();
@BeforeAll
static void setup() {
- Logger logger = (Logger) LoggerFactory.getLogger("org.mvndaemon.mvnd.client.DaemonConnector");
- logger.setLevel(Level.DEBUG);
- logger.addAppender(appender);
- appender.start();
+ MvndSimpleLogger logger =
+ (MvndSimpleLogger) LoggerFactory.getLogger("org.mvndaemon.mvnd.client.DaemonConnector");
+ logger.setLogLevel(LocationAwareLogger.DEBUG_INT);
+ MvndSimpleLogger.setLogSink(messages::add);
}
@AfterAll
static void tearDown() {
- Logger logger = (Logger) LoggerFactory.getLogger("org.mvndaemon.mvnd.client.DaemonConnector");
- logger.detachAppender(appender);
+ MvndSimpleLogger.setLogSink(null);
}
static String getDaemonArgs() {
- return appender.list.stream()
- .filter(e -> e.getMessage().contains("Starting daemon process"))
- .map(e -> e.getArgumentArray()[2].toString())
+ return messages.stream()
+ .filter(e -> e.contains("Starting daemon process"))
.findAny()
.orElseThrow();
}
@BeforeEach
void unitSetup() {
- appender.list.clear();
+ messages.clear();
}
}
diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MultiModuleTest.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MultiModuleTest.java
index 2695d7da5..12cf18449 100644
--- a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MultiModuleTest.java
+++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MultiModuleTest.java
@@ -74,7 +74,13 @@ void cleanInstall() throws IOException, InterruptedException {
Stream.of(installedJars).forEach(jar -> Assertions.assertThat(jar).doesNotExist());
final TestClientOutput output = new TestClientOutput();
- client.execute(output, "clean", "install", "-e").assertSuccess();
+ client.execute(
+ output,
+ "-Dorg.slf4j.simpleLogger.log.io.takari.maven.builder.smart=DEBUG",
+ "clean",
+ "install",
+ "-e")
+ .assertSuccess();
{
final List filteredMessages = output.getMessages().stream()
diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/MvndTestExtension.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/MvndTestExtension.java
index d4295d744..13eef6165 100644
--- a/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/MvndTestExtension.java
+++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/MvndTestExtension.java
@@ -238,8 +238,6 @@ public static MvndResource create(
LOG.info("Building with mrm-maven-plugin");
settingsPath = createSettings(testDir.resolve("settings.xml"), mrmRepoUrl);
}
- final Path logback =
- Paths.get("src/test/resources/logback/logback.xml").toAbsolutePath();
final Path home = deleteDir(testDir.resolve("home"));
final TestParameters parameters = new TestParameters(
testDir,
@@ -251,7 +249,6 @@ public static MvndResource create(
Paths.get(System.getProperty("java.home")).toAbsolutePath().normalize(),
localMavenRepository,
settingsPath,
- logback,
TimeUtils.toDuration(Environment.MVND_IDLE_TIMEOUT.getDefault()),
keepAlive != null && !keepAlive.isEmpty()
? TimeUtils.toDuration(keepAlive)
diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/TestParameters.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/TestParameters.java
index 2f8b291ea..fa7eb38d0 100644
--- a/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/TestParameters.java
+++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/TestParameters.java
@@ -40,7 +40,6 @@ public TestParameters(
Path javaHome,
Path localMavenRepository,
Path settings,
- Path logbackConfigurationPath,
Duration idleTimeout,
Duration keepAlive,
int maxLostKeepAlive,
@@ -55,7 +54,6 @@ public TestParameters(
.put(Environment.JAVA_HOME, javaHome)
.put(Environment.MAVEN_REPO_LOCAL, localMavenRepository)
.put(Environment.MAVEN_SETTINGS, settings)
- .put(Environment.MVND_LOGBACK, logbackConfigurationPath)
.put(Environment.MVND_IDLE_TIMEOUT, TimeUtils.printDuration(idleTimeout))
.put(Environment.MVND_KEEP_ALIVE, TimeUtils.printDuration(keepAlive))
.put(Environment.MVND_MAX_LOST_KEEP_ALIVE, maxLostKeepAlive)
@@ -83,7 +81,6 @@ public TestParameters withTransferProgress() {
value(Environment.JAVA_HOME).asPath(),
value(Environment.MAVEN_REPO_LOCAL).asPath(),
value(Environment.MAVEN_SETTINGS).asPath(),
- value(Environment.MVND_LOGBACK).asPath(),
value(Environment.MVND_IDLE_TIMEOUT).asDuration(),
value(Environment.MVND_KEEP_ALIVE).asDuration(),
value(Environment.MVND_MAX_LOST_KEEP_ALIVE).asInt(),
diff --git a/integration-tests/src/test/resources/logback/logback.xml b/integration-tests/src/test/resources/logback/logback.xml
deleted file mode 100644
index 573dc0785..000000000
--- a/integration-tests/src/test/resources/logback/logback.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
- ${mvnd.daemonStorage}/daemon-${mvnd.id}.log
-
- %d{HH:mm:ss.SSS} %.-1level %msg%n
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/logging/pom.xml b/logging/pom.xml
index 1f8898d94..c9794dad2 100644
--- a/logging/pom.xml
+++ b/logging/pom.xml
@@ -41,10 +41,6 @@
-
- ch.qos.logback
- logback-classic
-
org.slf4j
log4j-over-slf4j
@@ -59,4 +55,59 @@
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.6.0
+
+
+ extract
+
+ unpack
+
+
+
+
+ org.apache.maven
+ maven-slf4j-wrapper
+ ${maven4.version}
+ sources
+
+
+ org.slf4j
+ slf4j-simple
+ ${slf4j.version}
+ sources
+
+
+ org/apache/maven/logwrapper/*.java,org/slf4j/impl/*.java
+ **/StaticLoggerBinder.java,**/StaticMDCBinder.java
+ ${project.build.directory}/generated-sources/unpack
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 3.4.0
+
+
+ add-unpacked-source-dir
+
+ add-source
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/SimpleAppender.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/SimpleAppender.java
deleted file mode 100644
index 24b4f6861..000000000
--- a/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/SimpleAppender.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.mvndaemon.mvnd.logging.internal;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.classic.spi.IThrowableProxy;
-import ch.qos.logback.classic.spi.ThrowableProxyUtil;
-import ch.qos.logback.core.AppenderBase;
-import ch.qos.logback.core.CoreConstants;
-
-import static org.apache.maven.shared.utils.logging.MessageUtils.level;
-
-/**
- * This appender acts like the slf4j simple logger.
- * It's used
- */
-public class SimpleAppender extends AppenderBase {
-
- @Override
- protected void append(ILoggingEvent eventObject) {
- StringBuilder buf = new StringBuilder();
- buf.append('[');
- buf.append(renderLevel(eventObject.getLevel()));
- buf.append(']');
- buf.append(' ');
- buf.append(eventObject.getFormattedMessage());
- buf.append(CoreConstants.LINE_SEPARATOR);
- IThrowableProxy tp = eventObject.getThrowableProxy();
- if (tp != null) {
- buf.append(CoreConstants.LINE_SEPARATOR);
- buf.append(ThrowableProxyUtil.asString(tp));
- }
- System.out.print(buf.toString());
- }
-
- private String renderLevel(Level level) {
- switch (level.toInt()) {
- case Level.TRACE_INT:
- return level().debug("TRACE");
- case Level.DEBUG_INT:
- return level().debug("DEBUG");
- case Level.INFO_INT:
- return level().info("INFO");
- case Level.WARN_INT:
- return level().warning("WARNING");
- case Level.ERROR_INT:
- return level().error("ERROR");
- default:
- throw new IllegalStateException("Level " + level + " is unknown.");
- }
- }
-}
diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/ProjectBuildLogAppender.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/ProjectBuildLogAppender.java
index 64ea08720..15177c7da 100644
--- a/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/ProjectBuildLogAppender.java
+++ b/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/ProjectBuildLogAppender.java
@@ -18,24 +18,13 @@
*/
package org.mvndaemon.mvnd.logging.smart;
-import java.util.Map;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.PatternLayout;
-import ch.qos.logback.classic.pattern.ClassicConverter;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.AppenderBase;
-import ch.qos.logback.core.Context;
-import org.apache.maven.shared.utils.logging.LoggerLevelRenderer;
-import org.apache.maven.shared.utils.logging.MessageUtils;
-import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
+import org.slf4j.impl.MvndSimpleLogger;
/**
* Forwards log messages to the client.
*/
-public class ProjectBuildLogAppender extends AppenderBase implements AutoCloseable {
+public class ProjectBuildLogAppender implements AutoCloseable {
private static final String KEY_PROJECT_ID = "maven.project.id";
private static final ThreadLocal PROJECT_ID = new InheritableThreadLocal<>();
@@ -80,71 +69,20 @@ public static void updateMdc() {
}
}
- private static final String pattern = "[%level] %msg%n";
- private final PatternLayout layout;
private final BuildEventListener buildEventListener;
public ProjectBuildLogAppender(BuildEventListener buildEventListener) {
this.buildEventListener = buildEventListener;
- this.name = ProjectBuildLogAppender.class.getName();
- this.context = (Context) LoggerFactory.getILoggerFactory();
-
- final PatternLayout l = new PatternLayout();
- l.setContext(context);
- l.setPattern(pattern);
- final Map instanceConverterMap = l.getInstanceConverterMap();
- final String levelConverterClassName = LevelConverter.class.getName();
- instanceConverterMap.put("level", levelConverterClassName);
- instanceConverterMap.put("le", levelConverterClassName);
- instanceConverterMap.put("p", levelConverterClassName);
- this.layout = l;
-
- final Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
- root.addAppender(this);
-
- start();
+ MvndSimpleLogger.setLogSink(this::accept);
}
- @Override
- public void start() {
- layout.start();
- super.start();
- }
-
- @Override
- protected void append(ILoggingEvent event) {
- String projectId = event.getMDCPropertyMap().get(KEY_PROJECT_ID);
- buildEventListener.projectLogMessage(projectId, layout.doLayout(event));
- }
-
- public static class LevelConverter extends ClassicConverter {
- @Override
- public String convert(ILoggingEvent event) {
- LoggerLevelRenderer llr = MessageUtils.level();
- Level level = event.getLevel();
- switch (level.toInt()) {
- case Level.ERROR_INT:
- return llr.error(level.toString());
- case Level.WARN_INT:
- return llr.warning(level.toString());
- case Level.INFO_INT:
- return llr.info(level.toString());
- default:
- return llr.debug(level.toString());
- }
- }
- }
-
- @Override
- public void close() {
- stop();
- final Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
- root.detachAppender(this);
+ protected void accept(String message) {
+ String projectId = MDC.get(KEY_PROJECT_ID);
+ buildEventListener.projectLogMessage(projectId, message);
}
@Override
- public void stop() {
- layout.stop();
- super.stop();
+ public void close() throws Exception {
+ MvndSimpleLogger.setLogSink(null);
}
}
diff --git a/logging/src/main/java/org/slf4j/impl/MvndBaseLogger.java b/logging/src/main/java/org/slf4j/impl/MvndBaseLogger.java
new file mode 100644
index 000000000..5e44cefbd
--- /dev/null
+++ b/logging/src/main/java/org/slf4j/impl/MvndBaseLogger.java
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.slf4j.impl;
+
+import org.slf4j.event.LoggingEvent;
+import org.slf4j.helpers.FormattingTuple;
+import org.slf4j.helpers.MarkerIgnoringBase;
+import org.slf4j.helpers.MessageFormatter;
+import org.slf4j.spi.LocationAwareLogger;
+
+public abstract class MvndBaseLogger extends MarkerIgnoringBase {
+
+ protected static final int LOG_LEVEL_TRACE = LocationAwareLogger.TRACE_INT;
+ protected static final int LOG_LEVEL_DEBUG = LocationAwareLogger.DEBUG_INT;
+ protected static final int LOG_LEVEL_INFO = LocationAwareLogger.INFO_INT;
+ protected static final int LOG_LEVEL_WARN = LocationAwareLogger.WARN_INT;
+ protected static final int LOG_LEVEL_ERROR = LocationAwareLogger.ERROR_INT;
+
+ /** The current log level */
+ protected int currentLogLevel = LOG_LEVEL_INFO;
+
+ public MvndBaseLogger(String name) {
+ this.name = name;
+ }
+
+ protected void formatAndLog(int level, String format, Object arg1, Object arg2) {
+ if (!isLevelEnabled(level)) {
+ return;
+ }
+ FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
+ log(level, tp.getMessage(), tp.getThrowable());
+ }
+
+ protected void formatAndLog(int level, String format, Object... arguments) {
+ if (!isLevelEnabled(level)) {
+ return;
+ }
+ FormattingTuple tp = MessageFormatter.arrayFormat(format, arguments);
+ log(level, tp.getMessage(), tp.getThrowable());
+ }
+
+ protected void log(int level, String message, Throwable t) {
+ if (!isLevelEnabled(level)) {
+ return;
+ }
+ doLog(level, message, t);
+ }
+
+ protected abstract void doLog(int level, String message, Throwable t);
+
+ /**
+ * Is the given log level currently enabled?
+ *
+ * @param logLevel
+ * is this level enabled?
+ */
+ protected boolean isLevelEnabled(int logLevel) {
+ // log level are numerically ordered so can use simple numeric
+ // comparison
+ return (logLevel >= currentLogLevel);
+ }
+
+ /** Are {@code trace} messages currently enabled? */
+ public boolean isTraceEnabled() {
+ return isLevelEnabled(LOG_LEVEL_TRACE);
+ }
+
+ /**
+ * A simple implementation which logs messages of level TRACE according to
+ * the format outlined above.
+ */
+ public void trace(String msg) {
+ log(LOG_LEVEL_TRACE, msg, null);
+ }
+
+ /**
+ * Perform single parameter substitution before logging the message of level
+ * TRACE according to the format outlined above.
+ */
+ public void trace(String format, Object param1) {
+ formatAndLog(LOG_LEVEL_TRACE, format, param1, null);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * TRACE according to the format outlined above.
+ */
+ public void trace(String format, Object param1, Object param2) {
+ formatAndLog(LOG_LEVEL_TRACE, format, param1, param2);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * TRACE according to the format outlined above.
+ */
+ public void trace(String format, Object... argArray) {
+ formatAndLog(LOG_LEVEL_TRACE, format, argArray);
+ }
+
+ /** Log a message of level TRACE, including an exception. */
+ public void trace(String msg, Throwable t) {
+ log(LOG_LEVEL_TRACE, msg, t);
+ }
+
+ /** Are {@code debug} messages currently enabled? */
+ public boolean isDebugEnabled() {
+ return isLevelEnabled(LOG_LEVEL_DEBUG);
+ }
+
+ /**
+ * A simple implementation which logs messages of level DEBUG according to
+ * the format outlined above.
+ */
+ public void debug(String msg) {
+ log(LOG_LEVEL_DEBUG, msg, null);
+ }
+
+ /**
+ * Perform single parameter substitution before logging the message of level
+ * DEBUG according to the format outlined above.
+ */
+ public void debug(String format, Object param1) {
+ formatAndLog(LOG_LEVEL_DEBUG, format, param1, null);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * DEBUG according to the format outlined above.
+ */
+ public void debug(String format, Object param1, Object param2) {
+ formatAndLog(LOG_LEVEL_DEBUG, format, param1, param2);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * DEBUG according to the format outlined above.
+ */
+ public void debug(String format, Object... argArray) {
+ formatAndLog(LOG_LEVEL_DEBUG, format, argArray);
+ }
+
+ /** Log a message of level DEBUG, including an exception. */
+ public void debug(String msg, Throwable t) {
+ log(LOG_LEVEL_DEBUG, msg, t);
+ }
+
+ /** Are {@code info} messages currently enabled? */
+ public boolean isInfoEnabled() {
+ return isLevelEnabled(LOG_LEVEL_INFO);
+ }
+
+ /**
+ * A simple implementation which logs messages of level INFO according to
+ * the format outlined above.
+ */
+ public void info(String msg) {
+ log(LOG_LEVEL_INFO, msg, null);
+ }
+
+ /**
+ * Perform single parameter substitution before logging the message of level
+ * INFO according to the format outlined above.
+ */
+ public void info(String format, Object arg) {
+ formatAndLog(LOG_LEVEL_INFO, format, arg, null);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * INFO according to the format outlined above.
+ */
+ public void info(String format, Object arg1, Object arg2) {
+ formatAndLog(LOG_LEVEL_INFO, format, arg1, arg2);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * INFO according to the format outlined above.
+ */
+ public void info(String format, Object... argArray) {
+ formatAndLog(LOG_LEVEL_INFO, format, argArray);
+ }
+
+ /** Log a message of level INFO, including an exception. */
+ public void info(String msg, Throwable t) {
+ log(LOG_LEVEL_INFO, msg, t);
+ }
+
+ /** Are {@code warn} messages currently enabled? */
+ public boolean isWarnEnabled() {
+ return isLevelEnabled(LOG_LEVEL_WARN);
+ }
+
+ /**
+ * A simple implementation which always logs messages of level WARN
+ * according to the format outlined above.
+ */
+ public void warn(String msg) {
+ log(LOG_LEVEL_WARN, msg, null);
+ }
+
+ /**
+ * Perform single parameter substitution before logging the message of level
+ * WARN according to the format outlined above.
+ */
+ public void warn(String format, Object arg) {
+ formatAndLog(LOG_LEVEL_WARN, format, arg, null);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * WARN according to the format outlined above.
+ */
+ public void warn(String format, Object arg1, Object arg2) {
+ formatAndLog(LOG_LEVEL_WARN, format, arg1, arg2);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * WARN according to the format outlined above.
+ */
+ public void warn(String format, Object... argArray) {
+ formatAndLog(LOG_LEVEL_WARN, format, argArray);
+ }
+
+ /** Log a message of level WARN, including an exception. */
+ public void warn(String msg, Throwable t) {
+ log(LOG_LEVEL_WARN, msg, t);
+ }
+
+ /** Are {@code error} messages currently enabled? */
+ public boolean isErrorEnabled() {
+ return isLevelEnabled(LOG_LEVEL_ERROR);
+ }
+
+ /**
+ * A simple implementation which always logs messages of level ERROR
+ * according to the format outlined above.
+ */
+ public void error(String msg) {
+ log(LOG_LEVEL_ERROR, msg, null);
+ }
+
+ /**
+ * Perform single parameter substitution before logging the message of level
+ * ERROR according to the format outlined above.
+ */
+ public void error(String format, Object arg) {
+ formatAndLog(LOG_LEVEL_ERROR, format, arg, null);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * ERROR according to the format outlined above.
+ */
+ public void error(String format, Object arg1, Object arg2) {
+ formatAndLog(LOG_LEVEL_ERROR, format, arg1, arg2);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * ERROR according to the format outlined above.
+ */
+ public void error(String format, Object... argArray) {
+ formatAndLog(LOG_LEVEL_ERROR, format, argArray);
+ }
+
+ /** Log a message of level ERROR, including an exception. */
+ public void error(String msg, Throwable t) {
+ log(LOG_LEVEL_ERROR, msg, t);
+ }
+
+ public void log(LoggingEvent event) {
+ int levelInt = event.getLevel().toInt();
+
+ if (!isLevelEnabled(levelInt)) {
+ return;
+ }
+ FormattingTuple tp =
+ MessageFormatter.arrayFormat(event.getMessage(), event.getArgumentArray(), event.getThrowable());
+ log(levelInt, tp.getMessage(), event.getThrowable());
+ }
+}
diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/MvndSlf4jConfiguration.java b/logging/src/main/java/org/slf4j/impl/MvndConfiguration.java
similarity index 67%
rename from logging/src/main/java/org/mvndaemon/mvnd/logging/internal/MvndSlf4jConfiguration.java
rename to logging/src/main/java/org/slf4j/impl/MvndConfiguration.java
index 7e6ecf37f..e075a03e1 100644
--- a/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/MvndSlf4jConfiguration.java
+++ b/logging/src/main/java/org/slf4j/impl/MvndConfiguration.java
@@ -16,32 +16,36 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.mvndaemon.mvnd.logging.internal;
+package org.slf4j.impl;
import org.apache.maven.cli.logging.Slf4jConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.slf4j.ILoggerFactory;
-public class MvndSlf4jConfiguration implements Slf4jConfiguration {
+public class MvndConfiguration implements Slf4jConfiguration {
@Override
public void setRootLoggerLevel(Level level) {
- ch.qos.logback.classic.Level value;
+ String value;
switch (level) {
case DEBUG:
- value = ch.qos.logback.classic.Level.DEBUG;
+ value = "debug";
break;
case INFO:
- value = ch.qos.logback.classic.Level.INFO;
+ value = "info";
break;
default:
- value = ch.qos.logback.classic.Level.ERROR;
+ value = "error";
break;
}
- ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)).setLevel(value);
+ System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", value);
}
@Override
- public void activate() {}
+ public void activate() {
+ ILoggerFactory lf = StaticLoggerBinder.getSingleton().getLoggerFactory();
+ if (lf instanceof MvndLoggerFactory) {
+ ((MvndLoggerFactory) lf).reconfigure();
+ }
+ }
}
diff --git a/logging/src/main/java/org/slf4j/impl/MvndDaemonLogger.java b/logging/src/main/java/org/slf4j/impl/MvndDaemonLogger.java
new file mode 100644
index 000000000..02977aea4
--- /dev/null
+++ b/logging/src/main/java/org/slf4j/impl/MvndDaemonLogger.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.slf4j.impl;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+
+public class MvndDaemonLogger extends MvndBaseLogger {
+
+ final DateTimeFormatter dateTimeFormatter =
+ new DateTimeFormatterBuilder().appendPattern("HH:mm:ss.SSS").toFormatter();
+
+ PrintStream printStream;
+
+ public MvndDaemonLogger(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void doLog(int level, String message, Throwable t) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ pw.append(dateTimeFormatter.format(LocalTime.now()));
+ pw.append(" ");
+ switch (level) {
+ case LOG_LEVEL_ERROR:
+ pw.append("E");
+ break;
+ case LOG_LEVEL_WARN:
+ pw.append("W");
+ break;
+ case LOG_LEVEL_INFO:
+ pw.append("I");
+ break;
+ case LOG_LEVEL_DEBUG:
+ pw.append("D");
+ break;
+ case LOG_LEVEL_TRACE:
+ pw.append("T");
+ break;
+ }
+ pw.append(" ");
+ pw.append(message);
+ if (t != null) {
+ t.printStackTrace(pw);
+ }
+ PrintStream printStream = MvndSimpleLogger.CONFIG_PARAMS.outputChoice.getTargetPrintStream();
+ printStream.println(sw);
+ printStream.flush();
+ }
+}
diff --git a/logging/src/main/java/org/slf4j/impl/MvndFailOnSeverityLogger.java b/logging/src/main/java/org/slf4j/impl/MvndFailOnSeverityLogger.java
new file mode 100644
index 000000000..27b43fd68
--- /dev/null
+++ b/logging/src/main/java/org/slf4j/impl/MvndFailOnSeverityLogger.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.slf4j.impl;
+
+import org.apache.maven.logwrapper.LogLevelRecorder;
+import org.slf4j.event.Level;
+
+/**
+ * A proxy which enhances the MavenSimpleLogger with functionality to track whether a logging threshold is hit.
+ * Currently only support WARN and ERROR states, since it's been used for the --fail-on-severity flag.
+ */
+public class MvndFailOnSeverityLogger extends MvndSimpleLogger {
+ private final LogLevelRecorder logLevelRecorder;
+
+ MvndFailOnSeverityLogger(String name, LogLevelRecorder logLevelRecorder) {
+ super(name);
+ this.logLevelRecorder = logLevelRecorder;
+ }
+
+ /**
+ * A simple implementation which always logs messages of level WARN
+ * according to the format outlined above.
+ */
+ @Override
+ public void warn(String msg) {
+ super.warn(msg);
+ logLevelRecorder.record(Level.WARN);
+ }
+
+ /**
+ * Perform single parameter substitution before logging the message of level
+ * WARN according to the format outlined above.
+ */
+ @Override
+ public void warn(String format, Object arg) {
+ super.warn(format, arg);
+ logLevelRecorder.record(Level.WARN);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * WARN according to the format outlined above.
+ */
+ @Override
+ public void warn(String format, Object arg1, Object arg2) {
+ super.warn(format, arg1, arg2);
+ logLevelRecorder.record(Level.WARN);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * WARN according to the format outlined above.
+ */
+ @Override
+ public void warn(String format, Object... argArray) {
+ super.warn(format, argArray);
+ logLevelRecorder.record(Level.WARN);
+ }
+
+ /** Log a message of level WARN, including an exception. */
+ @Override
+ public void warn(String msg, Throwable t) {
+ super.warn(msg, t);
+ logLevelRecorder.record(Level.WARN);
+ }
+
+ /**
+ * A simple implementation which always logs messages of level ERROR
+ * according to the format outlined above.
+ */
+ @Override
+ public void error(String msg) {
+ super.error(msg);
+ logLevelRecorder.record(Level.ERROR);
+ }
+
+ /**
+ * Perform single parameter substitution before logging the message of level
+ * ERROR according to the format outlined above.
+ */
+ @Override
+ public void error(String format, Object arg) {
+ super.error(format, arg);
+ logLevelRecorder.record(Level.ERROR);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * ERROR according to the format outlined above.
+ */
+ @Override
+ public void error(String format, Object arg1, Object arg2) {
+ super.error(format, arg1, arg2);
+ logLevelRecorder.record(Level.ERROR);
+ }
+
+ /**
+ * Perform double parameter substitution before logging the message of level
+ * ERROR according to the format outlined above.
+ */
+ @Override
+ public void error(String format, Object... argArray) {
+ super.error(format, argArray);
+ logLevelRecorder.record(Level.ERROR);
+ }
+
+ /** Log a message of level ERROR, including an exception. */
+ @Override
+ public void error(String msg, Throwable t) {
+ super.error(msg, t);
+ logLevelRecorder.record(Level.ERROR);
+ }
+}
diff --git a/logging/src/main/java/org/slf4j/impl/MvndLoggerFactory.java b/logging/src/main/java/org/slf4j/impl/MvndLoggerFactory.java
new file mode 100644
index 000000000..7de5cba31
--- /dev/null
+++ b/logging/src/main/java/org/slf4j/impl/MvndLoggerFactory.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.slf4j.impl;
+
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.maven.logwrapper.LogLevelRecorder;
+import org.apache.maven.logwrapper.MavenSlf4jWrapperFactory;
+import org.slf4j.Logger;
+
+/**
+ * LogFactory for Maven which can create a simple logger or one which, if set, fails the build on a severity threshold.
+ */
+public class MvndLoggerFactory implements MavenSlf4jWrapperFactory {
+ private LogLevelRecorder logLevelRecorder = null;
+ private final ConcurrentMap loggerMap = new ConcurrentHashMap<>();
+
+ public MvndLoggerFactory() {
+ MvndSimpleLogger.lazyInit();
+ }
+
+ @Override
+ public void setLogLevelRecorder(LogLevelRecorder logLevelRecorder) {
+ if (this.logLevelRecorder != null) {
+ throw new IllegalStateException("LogLevelRecorder has already been set.");
+ }
+
+ this.logLevelRecorder = logLevelRecorder;
+ }
+
+ @Override
+ public Optional getLogLevelRecorder() {
+ return Optional.ofNullable(logLevelRecorder);
+ }
+
+ /**
+ * Return an appropriate {@link Logger} instance by name.
+ */
+ @Override
+ public Logger getLogger(String name) {
+ return loggerMap.computeIfAbsent(name, this::getNewLoggingInstance);
+ }
+
+ private Logger getNewLoggingInstance(String name) {
+ if (name.startsWith("org.mvndaemon.mvnd.daemon")) {
+ return new MvndDaemonLogger(name);
+ } else if (logLevelRecorder == null) {
+ return new MvndSimpleLogger(name);
+ } else {
+ return new MvndFailOnSeverityLogger(name, logLevelRecorder);
+ }
+ }
+
+ public void reconfigure() {
+ SimpleLoggerConfiguration config = MvndSimpleLogger.CONFIG_PARAMS;
+ config.init();
+ loggerMap.values().forEach(l -> {
+ if (l instanceof MvndSimpleLogger) {
+ ((MvndSimpleLogger) l).configure(config.defaultLogLevel);
+ }
+ });
+ }
+}
diff --git a/logging/src/main/java/org/slf4j/impl/MvndSimpleLogger.java b/logging/src/main/java/org/slf4j/impl/MvndSimpleLogger.java
new file mode 100644
index 000000000..f2041a53f
--- /dev/null
+++ b/logging/src/main/java/org/slf4j/impl/MvndSimpleLogger.java
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.slf4j.impl;
+
+import java.util.Date;
+import java.util.function.Consumer;
+
+import org.apache.maven.shared.utils.logging.MessageBuilder;
+import org.apache.maven.shared.utils.logging.MessageUtils;
+
+import static org.apache.maven.shared.utils.logging.MessageUtils.level;
+
+/**
+ * Logger for Maven, that support colorization of levels and stacktraces. This class implements 2 methods introduced in
+ * slf4j-simple provider local copy.
+ *
+ * @since 3.5.0
+ */
+public class MvndSimpleLogger extends MvndBaseLogger {
+
+ static final String TID_PREFIX = "tid=";
+
+ static long START_TIME = System.currentTimeMillis();
+
+ static boolean INITIALIZED = false;
+ static final SimpleLoggerConfiguration CONFIG_PARAMS = new SimpleLoggerConfiguration();
+
+ static void lazyInit() {
+ if (INITIALIZED) {
+ return;
+ }
+ INITIALIZED = true;
+ init();
+ }
+
+ // external software might be invoking this method directly. Do not rename
+ // or change its semantics.
+ static void init() {
+ CONFIG_PARAMS.init();
+ }
+
+ static Consumer LOG_SINK;
+
+ public static void setLogSink(Consumer logSink) {
+ LOG_SINK = logSink;
+ }
+
+ /** The short name of this simple log instance */
+ private transient String shortLogName = null;
+
+ MvndSimpleLogger(String name) {
+ super(name);
+ configure(CONFIG_PARAMS.defaultLogLevel);
+ }
+
+ String recursivelyComputeLevelString() {
+ String tempName = name;
+ String levelString = null;
+ int indexOfLastDot = tempName.length();
+ while ((levelString == null) && (indexOfLastDot > -1)) {
+ tempName = tempName.substring(0, indexOfLastDot);
+ levelString = CONFIG_PARAMS.getStringProperty(SimpleLogger.LOG_KEY_PREFIX + tempName, null);
+ indexOfLastDot = tempName.lastIndexOf(".");
+ }
+ return levelString;
+ }
+
+ @Override
+ protected void doLog(int level, String message, Throwable t) {
+ StringBuilder buf = new StringBuilder(32);
+
+ // Append date-time if so configured
+ if (CONFIG_PARAMS.showDateTime) {
+ if (CONFIG_PARAMS.dateFormatter != null) {
+ buf.append(getFormattedDate());
+ buf.append(' ');
+ } else {
+ buf.append(System.currentTimeMillis() - START_TIME);
+ buf.append(' ');
+ }
+ }
+
+ // Append current thread name if so configured
+ if (CONFIG_PARAMS.showThreadName) {
+ buf.append('[');
+ buf.append(Thread.currentThread().getName());
+ buf.append("] ");
+ }
+
+ if (CONFIG_PARAMS.showThreadId) {
+ buf.append(TID_PREFIX);
+ buf.append(Thread.currentThread().getId());
+ buf.append(' ');
+ }
+
+ if (CONFIG_PARAMS.levelInBrackets) buf.append('[');
+
+ // Append a readable representation of the log level
+ String levelStr = renderLevel(level);
+ buf.append(levelStr);
+ if (CONFIG_PARAMS.levelInBrackets) buf.append(']');
+ buf.append(' ');
+
+ // Append the name of the log instance if so configured
+ if (CONFIG_PARAMS.showShortLogName) {
+ if (shortLogName == null) shortLogName = computeShortName();
+ buf.append(String.valueOf(shortLogName)).append(" - ");
+ } else if (CONFIG_PARAMS.showLogName) {
+ buf.append(String.valueOf(name)).append(" - ");
+ }
+
+ // Append the message
+ buf.append(message);
+
+ writeThrowable(t, buf);
+
+ Consumer sink = LOG_SINK;
+ if (sink != null) {
+ sink.accept(buf.toString());
+ } else {
+ CONFIG_PARAMS.outputChoice.getTargetPrintStream().println(buf.toString());
+ }
+ }
+
+ protected String getFormattedDate() {
+ Date now = new Date();
+ return CONFIG_PARAMS.dateFormatter.format(now);
+ }
+
+ private String computeShortName() {
+ return name.substring(name.lastIndexOf(".") + 1);
+ }
+
+ protected String renderLevel(int level) {
+ switch (level) {
+ case LOG_LEVEL_TRACE:
+ return level().debug("TRACE").toString();
+ case LOG_LEVEL_DEBUG:
+ return level().debug("DEBUG").toString();
+ case LOG_LEVEL_INFO:
+ return level().info("INFO").toString();
+ case LOG_LEVEL_WARN:
+ return level().warning("WARNING").toString();
+ case LOG_LEVEL_ERROR:
+ default:
+ return level().error("ERROR").toString();
+ }
+ }
+
+ protected void writeThrowable(Throwable t, StringBuilder sb) {
+ if (t == null) {
+ return;
+ }
+ MessageBuilder builder = MessageUtils.buffer(sb);
+ builder.failure(t.getClass().getName());
+ if (t.getMessage() != null) {
+ builder.a(": ");
+ builder.failure(t.getMessage());
+ }
+ builder.newline();
+
+ printStackTrace(t, builder, "");
+ }
+
+ private void printStackTrace(Throwable t, MessageBuilder builder, String prefix) {
+ for (StackTraceElement e : t.getStackTrace()) {
+ builder.a(prefix);
+ builder.a(" ");
+ builder.strong("at");
+ builder.a(" " + e.getClassName() + "." + e.getMethodName());
+ builder.a(" (").strong(getLocation(e)).a(")");
+ builder.newline();
+ }
+ for (Throwable se : t.getSuppressed()) {
+ writeThrowable(se, builder, "Suppressed", prefix + " ");
+ }
+ Throwable cause = t.getCause();
+ if (cause != null) {
+ writeThrowable(cause, builder, "Caused by", prefix);
+ }
+ }
+
+ private void writeThrowable(Throwable t, MessageBuilder builder, String caption, String prefix) {
+ builder.a(prefix).strong(caption).a(": ").a(t.getClass().getName());
+ if (t.getMessage() != null) {
+ builder.a(": ");
+ builder.failure(t.getMessage());
+ }
+ builder.newline();
+
+ printStackTrace(t, builder, prefix);
+ }
+
+ protected String getLocation(final StackTraceElement e) {
+ assert e != null;
+
+ if (e.isNativeMethod()) {
+ return "Native Method";
+ } else if (e.getFileName() == null) {
+ return "Unknown Source";
+ } else if (e.getLineNumber() >= 0) {
+ return String.format("%s:%s", e.getFileName(), e.getLineNumber());
+ } else {
+ return e.getFileName();
+ }
+ }
+
+ public void configure(int defaultLogLevel) {
+ String levelString = recursivelyComputeLevelString();
+ if (levelString != null) {
+ this.currentLogLevel = SimpleLoggerConfiguration.stringToLevel(levelString);
+ } else {
+ this.currentLogLevel = defaultLogLevel;
+ }
+ }
+
+ public void setLogLevel(int logLevel) {
+ this.currentLogLevel = logLevel;
+ }
+}
diff --git a/logging/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/logging/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
new file mode 100644
index 000000000..2ebf87ba2
--- /dev/null
+++ b/logging/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.slf4j.impl;
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.spi.LoggerFactoryBinder;
+
+/**
+ * SLF4J LoggerFactoryBinder implementation using MavenSimpleLogger.
+ * This class is part of the required classes used to specify an
+ * SLF4J logger provider implementation.
+ *
+ * @since 3.5.1
+ */
+public final class StaticLoggerBinder implements LoggerFactoryBinder {
+ /**
+ * Declare the version of the SLF4J API this implementation is compiled
+ * against. The value of this field is usually modified with each release.
+ */
+ // to avoid constant folding by the compiler, this field must *not* be final
+ @SuppressWarnings({"checkstyle:staticvariablename", "checkstyle:visibilitymodifier"})
+ public static String REQUESTED_API_VERSION = "1.7.25"; // !final
+
+ private static final String LOGGER_FACTORY_CLASS_STR = MvndLoggerFactory.class.getName();
+
+ /**
+ * The unique instance of this class.
+ */
+ private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
+
+ /**
+ * The ILoggerFactory instance returned by the {@link #getLoggerFactory}
+ * method should always be the same object
+ */
+ private final ILoggerFactory loggerFactory;
+
+ /**
+ * Private constructor to prevent instantiation
+ */
+ private StaticLoggerBinder() {
+ loggerFactory = new MvndLoggerFactory();
+ }
+
+ /**
+ * Returns the singleton of this class.
+ */
+ public static StaticLoggerBinder getSingleton() {
+ return SINGLETON;
+ }
+
+ /**
+ * Returns the factory.
+ */
+ @Override
+ public ILoggerFactory getLoggerFactory() {
+ return loggerFactory;
+ }
+
+ /**
+ * Returns the class name.
+ */
+ @Override
+ public String getLoggerFactoryClassStr() {
+ return LOGGER_FACTORY_CLASS_STR;
+ }
+}
diff --git a/logging/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/logging/src/main/java/org/slf4j/impl/StaticMDCBinder.java
new file mode 100644
index 000000000..c264b1d1b
--- /dev/null
+++ b/logging/src/main/java/org/slf4j/impl/StaticMDCBinder.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.slf4j.impl;
+
+import org.slf4j.helpers.BasicMDCAdapter;
+import org.slf4j.spi.MDCAdapter;
+
+/**
+ * This implementation is bound to {@link BasicMDCAdapter}.
+ */
+public class StaticMDCBinder {
+
+ /**
+ * The unique instance of this class.
+ */
+ public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
+
+ private StaticMDCBinder() {}
+
+ /**
+ * Return the singleton of this class.
+ *
+ * @return the StaticMDCBinder singleton
+ * @since 1.7.14
+ */
+ public static final StaticMDCBinder getSingleton() {
+ return SINGLETON;
+ }
+
+ /**
+ * Currently this method always returns an instance of
+ * {@link StaticMDCBinder}.
+ */
+ public MDCAdapter getMDCA() {
+ return new BasicMDCAdapter();
+ }
+
+ public String getMDCAdapterClassStr() {
+ return BasicMDCAdapter.class.getName();
+ }
+}
diff --git a/logging/src/main/resources/META-INF/maven/slf4j-configuration.properties b/logging/src/main/resources/META-INF/maven/slf4j-configuration.properties
new file mode 100644
index 000000000..ee6529b86
--- /dev/null
+++ b/logging/src/main/resources/META-INF/maven/slf4j-configuration.properties
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# key = Slf4j effective logger factory implementation
+# value = corresponding o.a.m.cli.logging.Slf4jConfiguration class
+org.slf4j.impl.MvndLoggerFactory org.slf4j.impl.MvndConfiguration
diff --git a/pom.xml b/pom.xml
index 03456330a..ae3a09382 100644
--- a/pom.xml
+++ b/pom.xml
@@ -87,7 +87,6 @@
2.4.0
3.23.0
5.9.2
- 1.2.11
4.0.0-alpha-7
3.9.3
${maven.version}
@@ -122,16 +121,6 @@
-
- ch.qos.logback
- logback-classic
- ${logback.version}
-
-
- ch.qos.logback
- logback-core
- ${logback.version}
-
org.slf4j
slf4j-api