question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

org.apache.logging.log4j loggers not supported like test shows

See original GitHub issue

I’m working with apache.logging.log4j on existing classes, and followed the example test as below.

//Basic example class
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class FooService {

    private static final Logger LOGGER = LogManager.getLogger(FooService.class);

    public void sayHello() {
        LOGGER.info("Keyboard not responding. Press any key to continue...");
        LOGGER.warn("Congratulations, you are pregnant!");
    }

}

//Unit test:
import nl.altindag.log.LogCaptor;

public class FooServiceShould {
    @Test
    public void logInfoAndWarnMessages() {
        String expectedInfoMessage = "Keyboard not responding. Press any key to continue...";
        String expectedWarnMessage = "Congratulations, you are pregnant!";

        LogCaptor logCaptor = LogCaptor.forClass(FooService.class);
        //...
    }
}

However, i get the error shown below log4j-slf4j-impl cannot be present with log4j-to-slf4j using the same libraries as the demo.

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager; //all existing classes are already setup with these libs

public class Address {
    
    private static final Logger logger = LogManager.getLogger(Address.class);
    
    public Address(int a, int b, int c, int d) {
    	//other code
        logger.error("Address is malformed.");
    }
}

import nl.altindag.log.LogCaptor;

public class AddressTest {
    @Test
    public void testAddressValidation() {
        LogCaptor logCaptor = LogCaptor.forClass(Address.class);
        
        new Address(999,0,0,0);
        
        assertTrue(logCaptor.getErrorLogs().contains("Address is malformed."));
    }
}
org.apache.logging.log4j.LoggingException: log4j-slf4j-impl cannot be present with log4j-to-slf4j
	at org.apache.logging.slf4j.Log4jLoggerFactory.validateContext(Log4jLoggerFactory.java:49)
	at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:39)
	at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:30)
	at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:54)
	at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:30)
	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:363)
	at nl.altindag.log.LogCaptor.<init>(LogCaptor.java:49)
	at nl.altindag.log.LogCaptor.forClass(LogCaptor.java:69)
	at ....AddressTest.testAddressValidation(AddressTest.java:20)

and the console output

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:~/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.13.3/log4j-slf4j-impl-2.13.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:~/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]

I’m not sure if i’m applying the pom exclusions properly, but it seems like it might be easier to make a version that is compatible with org.apache.logging.log4j instead

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:15 (7 by maintainers)

github_iconTop GitHub Comments

4reactions
dereknheileycommented, Feb 5, 2021

Aha #2, removing the exclusion we tried adding for one of the above problems finally fixed it. So in summary, import the library before other log4j dependencies.

image

0reactions
Hakky54commented, Jul 17, 2021

Amazing, you found the solution. Interesting to see that the order of declaring the dependency in this specific use-case worked for you! I will note this solution down. Good luck asserting your log messages!

By the way I published here Java tutorials - LogCaptor isolated examples with different logging frameworks include this example and the adjustments to the pom which are included to get it working.

Update 14-07-2021 I noticed that you are using spring-boot-starter-log4j2. This library has some transitive dependencies which indeed requires adjustments to your pom. I have added an example for this use case, see the example project here: https://github.com/Hakky54/java-tutorials/tree/main/log-captor-examples/log-captor-with-spring-boot-starter-log4j2

So you basically need to add the following configuration to your pom:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <classpathDependencyExcludes>
                    <classpathDependencyExclude>org.apache.logging.log4j:log4j-slf4j-impl</classpathDependencyExclude>
                </classpathDependencyExcludes>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <configuration>
                <classpathDependencyExcludes>
                    <classpathDependencyExclude>org.apache.logging.log4j:log4j-slf4j-impl</classpathDependencyExclude>
                </classpathDependencyExcludes>
            </configuration>
        </plugin>
    </plugins>
</build>

This will exclude org.apache.logging.log4j:log4j-slf4j-impl from the classpath only during the test phase I mentioned this solution also at the beginning of our conversation, see here: https://github.com/Hakky54/log-captor/issues/6#issuecomment-770237736

Read more comments on GitHub >

github_iconTop Results From Across the Web

java - Caused by: org.apache.logging.log4j.LoggingException ...
e.g for a error msg like this: Caused by: org.apache.logging.log4j.LoggingException: log4j-slf4j-impl cannot be present with log4j-to-slf4j ...
Read more >
Log4j – Frequently Asked Questions - Apache Logging Services
This will display detailed log4j2-internal log statements on the console about what happens during the configuration process.
Read more >
26. Logging - Spring
Spring Boot uses Commons Logging for all internal logging but leaves the underlying log implementation open. Default configurations are provided for Java ...
Read more >
Log4j 2 Tutorial: Configuration Example for Logging in Java
LogManager; import org.apache.logging.log4j. ... logging configurations for tests, different configurations as the default for your codebase ...
Read more >
Logging Problems in IBM WebSphere Application Server
Log4J log /trace is not routed to WebSphere Application Server log/trace files, and Log4J loggers don't show up in the WebSphere Application ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found