diff --git a/apache-maven/src/test/java/org/slf4j/impl/MavenLoggerFactoryTest.java b/apache-maven/src/test/java/org/slf4j/impl/MavenLoggerFactoryTest.java
new file mode 100644
index 0000000000..352d627044
--- /dev/null
+++ b/apache-maven/src/test/java/org/slf4j/impl/MavenLoggerFactoryTest.java
@@ -0,0 +1,90 @@
+package org.slf4j.impl;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.logwrapper.LogLevelRecorder;
+import org.junit.Test;
+import org.slf4j.Logger;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public class MavenLoggerFactoryTest
+{
+ @Test
+ public void createsSimpleLogger()
+ {
+ MavenLoggerFactory mavenLoggerFactory = new MavenLoggerFactory();
+
+ Logger logger = mavenLoggerFactory.getLogger( "Test" );
+
+ assertThat( logger, instanceOf( MavenSimpleLogger.class ) );
+ }
+
+ @Test
+ public void loggerCachingWorks()
+ {
+ MavenLoggerFactory mavenLoggerFactory = new MavenLoggerFactory();
+
+ Logger logger = mavenLoggerFactory.getLogger( "Test" );
+ Logger logger2 = mavenLoggerFactory.getLogger( "Test" );
+ Logger differentLogger = mavenLoggerFactory.getLogger( "TestWithDifferentName" );
+
+ assertNotNull( logger );
+ assertNotNull( differentLogger );
+ assertSame( logger, logger2 );
+ assertNotSame( logger, differentLogger );
+ }
+
+ @Test
+ public void reportsWhenFailOnSeverityThresholdHasBeenHit()
+ {
+ MavenLoggerFactory mavenLoggerFactory = new MavenLoggerFactory();
+ mavenLoggerFactory.setLogLevelRecorder( new LogLevelRecorder( "ERROR" ) );
+
+ assertTrue( mavenLoggerFactory.getLogLevelRecorder().isPresent() );
+ LogLevelRecorder logLevelRecorder = mavenLoggerFactory.getLogLevelRecorder().get();
+
+ MavenFailOnSeverityLogger logger = (MavenFailOnSeverityLogger) mavenLoggerFactory.getLogger( "Test" );
+ assertFalse( logLevelRecorder.metThreshold() );
+
+ logger.warn( "This should not hit the fail threshold" );
+ assertFalse( logLevelRecorder.metThreshold() );
+
+ logger.error( "This should hit the fail threshold" );
+ assertTrue( logLevelRecorder.metThreshold() );
+
+ logger.warn( "This should not reset the fail threshold" );
+ assertTrue( logLevelRecorder.metThreshold() );
+ }
+
+ @Test( expected = IllegalStateException.class )
+ public void failOnSeverityThresholdCanOnlyBeSetOnce()
+ {
+ MavenLoggerFactory mavenLoggerFactory = new MavenLoggerFactory();
+ mavenLoggerFactory.setLogLevelRecorder( new LogLevelRecorder( "WARN" ) );
+ mavenLoggerFactory.setLogLevelRecorder( new LogLevelRecorder( "ERROR" ) );
+ }
+}
diff --git a/maven-embedder/pom.xml b/maven-embedder/pom.xml
index 235ae62388..f4982dac5b 100644
--- a/maven-embedder/pom.xml
+++ b/maven-embedder/pom.xml
@@ -74,6 +74,10 @@ under the License.
org.apache.maven.shared
maven-shared-utils
+
+ org.apache.maven
+ maven-slf4j-wrapper
+
com.google.inject
guice
@@ -104,10 +108,6 @@ under the License.
org.codehaus.mojo
animal-sniffer-annotations
-
- org.checkerframework
- checker-compat-qual
-
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
index 1e95010690..ec5e1b11c0 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
@@ -77,6 +77,8 @@ public class CLIManager
public static final String FAIL_FAST = "ff";
+ public static final String FAIL_ON_SEVERITY = "fos";
+
public static final String FAIL_AT_END = "fae";
public static final String FAIL_NEVER = "fn";
@@ -128,6 +130,7 @@ public CLIManager()
options.addOption( Option.builder( ALTERNATE_GLOBAL_SETTINGS ).longOpt( "global-settings" ).desc( "Alternate path for the global settings file" ).hasArg().build() );
options.addOption( Option.builder( Character.toString( ALTERNATE_USER_TOOLCHAINS ) ).longOpt( "toolchains" ).desc( "Alternate path for the user toolchains file" ).hasArg().build() );
options.addOption( Option.builder( ALTERNATE_GLOBAL_TOOLCHAINS ).longOpt( "global-toolchains" ).desc( "Alternate path for the global toolchains file" ).hasArg().build() );
+ options.addOption( Option.builder( FAIL_ON_SEVERITY ).longOpt( "fail-on-severity" ).desc( "Configure which severity of logging should cause the build to fail" ).hasArgs().build() );
options.addOption( Option.builder( FAIL_FAST ).longOpt( "fail-fast" ).desc( "Stop at first failure in reactorized builds" ).build() );
options.addOption( Option.builder( FAIL_AT_END ).longOpt( "fail-at-end" ).desc( "Only fail the build afterwards; allow all non-impacted builds to continue" ).build() );
options.addOption( Option.builder( FAIL_NEVER ).longOpt( "fail-never" ).desc( "NEVER fail the build, regardless of project result" ).build() );
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
index 7d17e187d2..8653c27174 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
@@ -58,6 +58,8 @@
import org.apache.maven.extension.internal.CoreExports;
import org.apache.maven.extension.internal.CoreExtensionEntry;
import org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.logwrapper.LogLevelRecorder;
+import org.apache.maven.logwrapper.MavenSlf4jWrapperFactory;
import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.properties.internal.EnvironmentUtils;
@@ -542,6 +544,24 @@ else if ( cliRequest.commandLine.hasOption( CLIManager.BATCH_MODE )
plexusLoggerManager = new Slf4jLoggerManager();
slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );
+
+ if ( cliRequest.commandLine.hasOption( CLIManager.FAIL_ON_SEVERITY ) )
+ {
+ String logLevelThreshold = cliRequest.commandLine.getOptionValue( CLIManager.FAIL_ON_SEVERITY );
+
+ if ( slf4jLoggerFactory instanceof MavenSlf4jWrapperFactory )
+ {
+ LogLevelRecorder logLevelRecorder = new LogLevelRecorder( logLevelThreshold );
+ ( (MavenSlf4jWrapperFactory) slf4jLoggerFactory ).setLogLevelRecorder( logLevelRecorder );
+ slf4jLogger.info( "Enabled to break the build on log level {}.", logLevelThreshold );
+ }
+ else
+ {
+ slf4jLogger.warn( "Expected LoggerFactory to be of type '{}', but found '{}' instead. "
+ + "The --fail-on-severity flag will not take effect.",
+ MavenSlf4jWrapperFactory.class.getName(), slf4jLoggerFactory.getClass().getName() );
+ }
+ }
}
private void version( CliRequest cliRequest )
@@ -1343,6 +1363,8 @@ private MavenExecutionRequest populateRequest( CliRequest cliRequest, MavenExecu
// this is the default behavior.
String reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
+ slf4jLoggerFactory = LoggerFactory.getILoggerFactory();
+
if ( commandLine.hasOption( CLIManager.NON_RECURSIVE ) )
{
recursive = false;
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java b/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java
index 17da65548a..f3cd8580b6 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java
@@ -33,11 +33,14 @@
import org.apache.maven.execution.ExecutionEvent;
import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.execution.MavenSession;
+import org.apache.maven.logwrapper.LogLevelRecorder;
+import org.apache.maven.logwrapper.MavenSlf4jWrapperFactory;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.utils.logging.MessageBuilder;
import org.codehaus.plexus.util.StringUtils;
+import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,8 +49,7 @@
*
* @author Benjamin Bentmann
*/
-public class ExecutionEventLogger
- extends AbstractExecutionListener
+public class ExecutionEventLogger extends AbstractExecutionListener
{
private final Logger logger;
@@ -133,6 +135,20 @@ public void sessionEnded( ExecutionEvent event )
logReactorSummary( event.getSession() );
}
+ ILoggerFactory iLoggerFactory = LoggerFactory.getILoggerFactory();
+
+ if ( iLoggerFactory instanceof MavenSlf4jWrapperFactory )
+ {
+ MavenSlf4jWrapperFactory loggerFactory = (MavenSlf4jWrapperFactory) iLoggerFactory;
+ loggerFactory.getLogLevelRecorder()
+ .filter( LogLevelRecorder::metThreshold )
+ .ifPresent( recorder ->
+ event.getSession().getResult().addException( new Exception(
+ "Build failed due to log statements with a higher severity than allowed. "
+ + "Fix the logged issues or remove flag --fail-on-severity (-fos)." ) )
+ );
+ }
+
logResult( event.getSession() );
logStats( event.getSession() );
@@ -298,16 +314,16 @@ public void projectStarted( ExecutionEvent event )
// -------< groupId:artifactId >-------
String projectKey = project.getGroupId() + ':' + project.getArtifactId();
-
- final String preHeader = "--< ";
+
+ final String preHeader = "--< ";
final String postHeader = " >--";
final int headerLen = preHeader.length() + projectKey.length() + postHeader.length();
String prefix = chars( '-', Math.max( 0, ( LINE_LENGTH - headerLen ) / 2 ) ) + preHeader;
- String suffix = postHeader
- + chars( '-', Math.max( 0, LINE_LENGTH - headerLen - prefix.length() + preHeader.length() ) );
+ String suffix = postHeader + chars( '-',
+ Math.max( 0, LINE_LENGTH - headerLen - prefix.length() + preHeader.length() ) );
logger.info( buffer().strong( prefix ).project( projectKey ).strong( suffix ).toString() );
diff --git a/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties b/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties
index ff865bccab..23b18c024a 100644
--- a/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties
+++ b/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties
@@ -18,6 +18,6 @@
# key = Slf4j effective logger factory implementation
# value = corresponding o.a.m.cli.logging.Slf4jConfiguration class
org.slf4j.impl.SimpleLoggerFactory org.apache.maven.cli.logging.impl.Slf4jSimpleConfiguration
-org.slf4j.impl.MavenSimpleLoggerFactory org.apache.maven.cli.logging.impl.Slf4jSimpleConfiguration
+org.slf4j.impl.MavenLoggerFactory org.apache.maven.cli.logging.impl.Slf4jSimpleConfiguration
org.apache.logging.slf4j.Log4jLoggerFactory org.apache.maven.cli.logging.impl.Log4j2Configuration
ch.qos.logback.classic.LoggerContext org.apache.maven.cli.logging.impl.LogbackConfiguration
diff --git a/maven-slf4j-provider/pom.xml b/maven-slf4j-provider/pom.xml
index defe2dddb5..7af239cdc5 100644
--- a/maven-slf4j-provider/pom.xml
+++ b/maven-slf4j-provider/pom.xml
@@ -45,6 +45,10 @@ under the License.
org.apache.maven.shared
maven-shared-utils
+
+ org.apache.maven
+ maven-slf4j-wrapper
+
diff --git a/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenFailOnSeverityLogger.java b/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenFailOnSeverityLogger.java
new file mode 100644
index 0000000000..12c6cc24e7
--- /dev/null
+++ b/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenFailOnSeverityLogger.java
@@ -0,0 +1,142 @@
+package org.slf4j.impl;
+
+/*
+ * 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.
+ */
+
+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 MavenFailOnSeverityLogger extends MavenSimpleLogger
+{
+ private final LogLevelRecorder logLevelRecorder;
+
+ MavenFailOnSeverityLogger( 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/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenLoggerFactory.java b/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenLoggerFactory.java
new file mode 100644
index 0000000000..7ef126d12c
--- /dev/null
+++ b/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenLoggerFactory.java
@@ -0,0 +1,82 @@
+package org.slf4j.impl;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.logwrapper.LogLevelRecorder;
+import org.apache.maven.logwrapper.MavenSlf4jWrapperFactory;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+/**
+ * LogFactory for Maven which can create a simple logger or one which, if set, fails the build on a severity threshold.
+ */
+public class MavenLoggerFactory extends SimpleLoggerFactory implements MavenSlf4jWrapperFactory
+{
+ private LogLevelRecorder logLevelRecorder = null;
+
+ @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 MavenSimpleLogger} instance by name.
+ */
+ @Override
+ public Logger getLogger( String name )
+ {
+ Logger simpleLogger = loggerMap.get( name );
+ if ( simpleLogger != null )
+ {
+ return simpleLogger;
+ }
+ else
+ {
+ Logger newInstance = getNewLoggingInstance( name );
+ Logger oldInstance = loggerMap.putIfAbsent( name, newInstance );
+ return oldInstance == null ? newInstance : oldInstance;
+ }
+ }
+
+ private Logger getNewLoggingInstance( String name )
+ {
+ if ( logLevelRecorder == null )
+ {
+ return new MavenSimpleLogger( name );
+ }
+ else
+ {
+ return new MavenFailOnSeverityLogger( name, logLevelRecorder );
+ }
+ }
+}
diff --git a/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLogger.java b/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLogger.java
index 9366687edb..767220d9ea 100644
--- a/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLogger.java
+++ b/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLogger.java
@@ -19,18 +19,18 @@
* under the License.
*/
-import static org.apache.maven.shared.utils.logging.MessageUtils.level;
-import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
-
import java.io.PrintStream;
+import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
+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.
+ * 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 MavenSimpleLogger
- extends SimpleLogger
+public class MavenSimpleLogger extends SimpleLogger
{
MavenSimpleLogger( String name )
{
diff --git a/maven-slf4j-provider/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/maven-slf4j-provider/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
index ba01d83226..ed94c70a7c 100644
--- a/maven-slf4j-provider/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
+++ b/maven-slf4j-provider/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
@@ -40,7 +40,7 @@ public final class StaticLoggerBinder
@SuppressWarnings( { "checkstyle:staticvariablename", "checkstyle:visibilitymodifier" } )
public static String REQUESTED_API_VERSION = "1.7.25"; // !final
- private static final String LOGGER_FACTORY_CLASS_STR = MavenSimpleLoggerFactory.class.getName();
+ private static final String LOGGER_FACTORY_CLASS_STR = MavenLoggerFactory.class.getName();
/**
* The unique instance of this class.
@@ -58,7 +58,7 @@ public final class StaticLoggerBinder
*/
private StaticLoggerBinder()
{
- loggerFactory = new MavenSimpleLoggerFactory();
+ loggerFactory = new MavenLoggerFactory();
}
/**
diff --git a/maven-slf4j-wrapper/pom.xml b/maven-slf4j-wrapper/pom.xml
new file mode 100644
index 0000000000..746c328226
--- /dev/null
+++ b/maven-slf4j-wrapper/pom.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+ 4.0.0
+
+
+ org.apache.maven
+ maven
+ 3.7.0-SNAPSHOT
+
+
+ maven-slf4j-wrapper
+
+ Maven SLF4J Wrapper
+
+ This modules provides an ILoggerFactory interface which avoids a cyclic dependency between maven-embedder and maven-slf4j-provider.
+
+
+
+
+ org.slf4j
+ slf4j-api
+
+
+
\ No newline at end of file
diff --git a/maven-slf4j-wrapper/src/main/java/org/apache/maven/logwrapper/LogLevelRecorder.java b/maven-slf4j-wrapper/src/main/java/org/apache/maven/logwrapper/LogLevelRecorder.java
new file mode 100644
index 0000000000..9fa4b51307
--- /dev/null
+++ b/maven-slf4j-wrapper/src/main/java/org/apache/maven/logwrapper/LogLevelRecorder.java
@@ -0,0 +1,55 @@
+package org.apache.maven.logwrapper;
+
+/*
+ * 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.
+ */
+
+import org.slf4j.event.Level;
+
+/**
+ * Responsible for keeping state of whether the threshold of the --fail-on-severity flag has been hit.
+ */
+public class LogLevelRecorder
+{
+ private final Level logThreshold;
+ private boolean metThreshold = false;
+
+ public LogLevelRecorder( String threshold )
+ {
+ Level level = Level.valueOf( threshold );
+ if ( level.toInt() < Level.WARN.toInt() )
+ {
+ throw new IllegalArgumentException( "Logging severity thresholds can only be set to WARN or ERROR" );
+ }
+
+ logThreshold = level;
+ }
+
+ public void record( Level logLevel )
+ {
+ if ( !metThreshold && logLevel.toInt() >= logThreshold.toInt() )
+ {
+ metThreshold = true;
+ }
+ }
+
+ public boolean metThreshold()
+ {
+ return metThreshold;
+ }
+}
diff --git a/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLoggerFactory.java b/maven-slf4j-wrapper/src/main/java/org/apache/maven/logwrapper/MavenSlf4jWrapperFactory.java
similarity index 54%
rename from maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLoggerFactory.java
rename to maven-slf4j-wrapper/src/main/java/org/apache/maven/logwrapper/MavenSlf4jWrapperFactory.java
index 4adfdbe059..e2063b73a3 100644
--- a/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLoggerFactory.java
+++ b/maven-slf4j-wrapper/src/main/java/org/apache/maven/logwrapper/MavenSlf4jWrapperFactory.java
@@ -1,4 +1,4 @@
-package org.slf4j.impl;
+package org.apache.maven.logwrapper;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,29 +19,15 @@
* under the License.
*/
-import org.slf4j.Logger;
+import org.slf4j.ILoggerFactory;
+
+import java.util.Optional;
/**
- * MavenSimpleLoggerFactory
+ * Wrapper for creating loggers which can have a log level threshold.
*/
-public class MavenSimpleLoggerFactory
- extends SimpleLoggerFactory
+public interface MavenSlf4jWrapperFactory extends ILoggerFactory
{
- /**
- * Return an appropriate {@link MavenSimpleLogger} instance by name.
- */
- public Logger getLogger( String name )
- {
- Logger simpleLogger = loggerMap.get( name );
- if ( simpleLogger != null )
- {
- return simpleLogger;
- }
- else
- {
- Logger newInstance = new MavenSimpleLogger( name );
- Logger oldInstance = loggerMap.putIfAbsent( name, newInstance );
- return oldInstance == null ? newInstance : oldInstance;
- }
- }
+ void setLogLevelRecorder( LogLevelRecorder logLevelRecorder );
+ Optional getLogLevelRecorder();
}
diff --git a/maven-slf4j-wrapper/src/site/site.xml b/maven-slf4j-wrapper/src/site/site.xml
new file mode 100644
index 0000000000..e475330c40
--- /dev/null
+++ b/maven-slf4j-wrapper/src/site/site.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+ ${project.scm.url}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/maven-slf4j-wrapper/src/test/java/org/apache/maven/logwrapper/LogLevelRecorderTest.java b/maven-slf4j-wrapper/src/test/java/org/apache/maven/logwrapper/LogLevelRecorderTest.java
new file mode 100644
index 0000000000..69b2853624
--- /dev/null
+++ b/maven-slf4j-wrapper/src/test/java/org/apache/maven/logwrapper/LogLevelRecorderTest.java
@@ -0,0 +1,49 @@
+package org.apache.maven.logwrapper;
+
+/*
+ * 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.
+ */
+
+import org.junit.Test;
+import org.slf4j.event.Level;
+
+import static org.junit.Assert.assertTrue;
+
+public class LogLevelRecorderTest
+{
+ @Test
+ public void createsLogLevelRecorder()
+ {
+ LogLevelRecorder logLevelRecorder = new LogLevelRecorder( "WARN" );
+ logLevelRecorder.record( Level.ERROR );
+
+ assertTrue( logLevelRecorder.metThreshold() );
+ }
+
+ @Test( expected = IllegalArgumentException.class )
+ public void failsOnLowerThanWarn ()
+ {
+ new LogLevelRecorder( "INFO" );
+ }
+
+ @Test( expected = IllegalArgumentException.class )
+ public void failsOnUnknownLogLevel ()
+ {
+ new LogLevelRecorder( "SEVERE" );
+ }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 3e73b2fb0b..21c05abf5b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -92,6 +92,7 @@ under the License.
maven-resolver-provider
maven-repository-metadata
maven-slf4j-provider
+ maven-slf4j-wrapper
maven-embedder
maven-compat
apache-maven
@@ -157,7 +158,13 @@ under the License.
Mike Mol (MNG-6665)
- Martin Kanters (MNG-6665)
+ Martin Kanters (MNG-6665, MNG-6065)
+
+
+ Luc Klaassen (MNG-6065)
+
+
+ Wouter Aarts (MNG-6065)
@@ -232,6 +239,11 @@ under the License.
maven-slf4j-provider
${project.version}
+
+ org.apache.maven
+ maven-slf4j-wrapper
+ ${project.version}
+