On 16 Mar 2013, at 23:38, Stuart McCulloch wrote:

> On 16 Mar 2013, at 13:58, Jason van Zyl wrote:
> 
>> Hervé,
>> 
>> Can you take a look at the logging changes you made to try and use the SLF4J 
>> package private method for resetting the logger? The streams are being reset 
>> correctly but the logging level doesn't appear to be reset which causes the 
>> embedded ITs to fail.
> 
> Did some investigating and the issue seems to be that SLF4J Simple uses a 
> static singleton logger factory which contains a map of cached loggers.
> 
> Because embedded test mode uses the same classloader for all the tests (it 
> only forks once at the start) each test therefore sees the same logger 
> factory and any previously cached loggers.

^ minor clarification, the classloader here is the one created by 
maven-verifier around the maven installation to-be-tested in embedded mode and 
not the surefire isolated classloader

> This means that although the MavenCLI successfully resets SLF4J to refresh 
> the log level, the new setting doesn't affect previously cached loggers (they 
> only pick up the level in their constructor).
> 
> This can be shown with the following hack to clear the logger map (not sane 
> code, just proof-of-concept) which solves the embedded logging IT failures:
> 
> diff --git 
> a/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/Slf4jSimpleConfiguration.java
>  
> b/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/Slf4jSimpleConfiguration.java
> index 6a7f385..f1af143 100644
> --- 
> a/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/Slf4jSimpleConfiguration.java
> +++ 
> b/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/Slf4jSimpleConfiguration.java
> @@ -58,5 +58,20 @@ public void activate()
>         // property for root logger level or System.out redirection need to 
> be taken into account
>         MavenSlf4jFriend.reset();
>         MavenSlf4jSimpleFriend.init();
> +
> +        try
> +        {
> +             org.slf4j.ILoggerFactory loggerFactory = 
> org.slf4j.LoggerFactory.getILoggerFactory();
> +             synchronized ( loggerFactory )
> +             {
> +                 java.lang.reflect.Field loggerMap = 
> loggerFactory.getClass().getDeclaredField( "loggerMap" );
> +                 loggerMap.setAccessible( true );
> +                 ( (java.util.Map) loggerMap.get( loggerFactory ) ).clear();
> +             }
> +        }
> +        catch ( Exception e )
> +        {
> +            // ignore for now...
> +        }
>     }
> }
> 
>> Thanks,
>> 
>> Jason
>> 
>> ----------------------------------------------------------
>> Jason van Zyl
>> Founder & CTO, Sonatype
>> Founder,  Apache Maven
>> http://twitter.com/jvanzyl
>> ---------------------------------------------------------
>> 
>> People develop abstractions by generalizing from concrete examples.
>> Every attempt to determine the correct abstraction on paper without
>> actually developing a running system is doomed to failure. No one
>> is that smart. A framework is a resuable design, so you develop it by
>> looking at the things it is supposed to be a design of. The more examples
>> you look at, the more general your framework will be.
>> 
>> -- Ralph Johnson & Don Roberts, Patterns for Evolving Frameworks 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to