You can debug logging using System.out. Using your code add the printConfig
method and call it with @AfterAll. When I do this with your code and run ./gradlew build
I get the following output:
FileProcessorTest STANDARD_ERROR
java.util.logging.config.class was null
java.util.logging.config.file was null
LogManager=org.apache.logging.log4j.jul.LogManager
scn=CoreLogger, n=, uph=true, l=WARNING, fl=null
->org.slf4j.bridge.SLF4JBridgeHandler, h=ALL, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=javax.management.timer, uph=true, l=null, fl=null
scn=CoreLogger, n=org.junit.platform.launcher.core.LauncherConfigurationParameters, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.platform.launcher.core.EngineDiscoveryOrchestrator, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.descriptor.JupiterTestDescriptor, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.platform.launcher.core.ServiceLoaderTestExecutionListenerRegistry, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.descriptor.MethodBasedTestDescriptor, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.execution.JupiterEngineExecutionContext, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.discovery.MethodOrderingVisitor, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.platform.launcher.core.InternalTestPlan, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=javax.management.monitor, uph=true, l=null, fl=null
scn=CoreLogger, n=javax.management.notification, uph=true, l=null, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.execution.ConditionEvaluator, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=javax.management.mbeanserver, uph=true, l=null, fl=null
scn=CoreLogger, n=org.junit.platform.launcher.core.ServiceLoaderPostDiscoveryFilterRegistry, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.extension.TimeoutConfiguration, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.platform.launcher.core.TestExecutionListenerRegistry, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.extension.MutableExtensionRegistry, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.discovery.MethodSelectorResolver, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=javax.management.relation, uph=true, l=null, fl=null
scn=CoreLogger, n=javax.management.modelmbean, uph=true, l=null, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.execution.ExecutableInvoker, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.javamoney.moneta.spi.MoneyUtils, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=javax.management, uph=true, l=null, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.config.InstantiatingConfigurationParameterConverter, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.platform.launcher.core.EngineIdValidator, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.descriptor.DisplayNameUtils, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.support.OpenTest4JAndJUnit4AwareThrowableCollector, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.platform.commons.util.ReflectionUtils, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=javax.management.misc, uph=true, l=null, fl=null
scn=CoreLogger, n=org.junit.platform.engine.support.hierarchical.NodeTestTask, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.javamoney.moneta.spi.MonetaryConfig, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=javax.management.mlet, uph=true, l=null, fl=null
scn=CoreLogger, n=org.junit.jupiter.engine.config.EnumConfigurationParameterConverter, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.junit.platform.commons.util.ClasspathScanner, uph=true, l=SEVERE, fl=null
scn=CoreLogger, n=org.javamoney.moneta.DefaultMonetaryContextFactory, uph=true, l=SEVERE, fl=null
The takeaways are:
- org.apache.logging.log4j.jul.LogManager is installed. [PASS]
- org.slf4j.bridge.SLF4JBridgeHandler is installed and set to ALL. Your code is using log4j but it appears that SLF4J is setup too [WARN]
- All loggers are publishing to SLF4JBridgeHandler per
uph=true
[PASS]
- There are no
com.xenoterracide
loggers. Project uses logj. [PASS]
- Root logger is set set to WARNING. Will only see WARN and ERROR. [QUESTIONABLE]
- Child loggers are a mix of null and SEVERE. Will only see WARN and ERROR.[QUESTIONABLE]
So lets run this again but without the log4j.jul.LogManager set in either place and I'll use System.out:
FileProcessorTest STANDARD_OUT
java.util.logging.config.class was null
java.util.logging.config.file was null
LogManager=java.util.logging.LogManager
scn=RootLogger, n=, uph=true, l=INFO, fl=null
->java.util.logging.ConsoleHandler, h=INFO, fl=null
scn=Logger, n=org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation, uph=true, l=null, fl=null
scn=Logger, n=javax.management.timer, uph=true, l=null, fl=null
scn=Logger, n=global, uph=true, l=null, fl=null
scn=Logger, n=org.junit.platform.launcher.core.LauncherConfigurationParameters, uph=true, l=null, fl=null
scn=Logger, n=org.junit.platform.launcher.core.EngineDiscoveryOrchestrator, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.descriptor.JupiterTestDescriptor, uph=true, l=null, fl=null
scn=Logger, n=org.junit.platform.launcher.core.ServiceLoaderTestExecutionListenerRegistry, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.descriptor.MethodBasedTestDescriptor, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.execution.JupiterEngineExecutionContext, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.discovery.MethodOrderingVisitor, uph=true, l=null, fl=null
scn=Logger, n=org.junit.platform.launcher.core.InternalTestPlan, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.execution.ConditionEvaluator, uph=true, l=null, fl=null
scn=Logger, n=javax.management.monitor, uph=true, l=null, fl=null
scn=Logger, n=javax.management.notification, uph=true, l=null, fl=null
scn=Logger, n=javax.management.mbeanserver, uph=true, l=null, fl=null
scn=Logger, n=org.junit.platform.launcher.core.ServiceLoaderPostDiscoveryFilterRegistry, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.extension.TimeoutConfiguration, uph=true, l=null, fl=null
scn=Logger, n=org.junit.platform.launcher.core.TestExecutionListenerRegistry, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.extension.MutableExtensionRegistry, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.discovery.MethodSelectorResolver, uph=true, l=null, fl=null
scn=Logger, n=javax.management.relation, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.execution.ExecutableInvoker, uph=true, l=null, fl=null
scn=Logger, n=javax.management.modelmbean, uph=true, l=null, fl=null
scn=Logger, n=org.javamoney.moneta.spi.MoneyUtils, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.config.InstantiatingConfigurationParameterConverter, uph=true, l=null, fl=null
scn=Logger, n=javax.management, uph=true, l=null, fl=null
scn=Logger, n=org.junit.platform.launcher.core.EngineIdValidator, uph=true, l=null, fl=null
scn=Logger, n=org.javamoney.moneta.Money, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.descriptor.DisplayNameUtils, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.support.OpenTest4JAndJUnit4AwareThrowableCollector, uph=true, l=null, fl=null
scn=Logger, n=org.junit.platform.commons.util.ReflectionUtils, uph=true, l=null, fl=null
scn=Logger, n=javax.management.misc, uph=true, l=null, fl=null
scn=Logger, n=org.junit.platform.engine.support.hierarchical.NodeTestTask, uph=true, l=null, fl=null
scn=Logger, n=org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry, uph=true, l=null, fl=null
scn=Logger, n=org.javamoney.moneta.spi.MonetaryConfig, uph=true, l=null, fl=null
scn=Logger, n=org.junit.jupiter.engine.config.EnumConfigurationParameterConverter, uph=true, l=null, fl=null
scn=Logger, n=org.junit.platform.commons.util.ClasspathScanner, uph=true, l=null, fl=null
scn=Logger, n=javax.management.mlet, uph=true, l=null, fl=null
scn=Logger, n=org.javamoney.moneta.DefaultMonetaryContextFactory, uph=true, l=null, fl=null
Now when I compare the two runs you can see:
- When log4j log manager is running the levels are either WARNING inherited from the root logger or SEVERE set on the child logger.
- When running the JUL log manager the levels are all inheriting INFO.
I think the issue you are seeing is in Application.java#L54.
- You need to set the root logger level to the given level.
builder.add( builder.newRootLogger( level )
- The log4j configuration is not updating the JUL logger levels correctly. This points to an error in Application::configureLog4j.
- The org.slf4j.bridge.SLF4JBridgeHandler is not installed. Perhaps when the bridge handler was installed the output was going to SLF4J and there was no console appender setup for SLF4J.
One thing you could try would be to explicitly exclude the jul-to-slf4j package. Maybe that will allow logj4 to take control of jul instead of slf4j. There is also a related information Java logging: slf4j over jul and log4j2.