Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log4j 2 hangs when creating logger

Tags:

java

log4j2

I have this simple program:

package myPackage;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

public class Test {
    private static Logger logger; 

    public static void main(String[] args) throws Exception {
        System.out.println("Creating logger...");
        logger = LogManager.getLogger(Test.class); 
        System.out.println("Logger created.");
        logger.info("Hello world!");
    }
}

If I run the program under the debugger, it prints:

Creating logger...

and then hangs.

If I run the program without debugger, it prints:

Exception in thread "main" java.lang.StackOverflowError
    at sun.reflect.Reflection.quickCheckMemberAccess(Reflection.java:84)
    at java.lang.reflect.Method.invoke(Method.java:489)
    at org.apache.logging.log4j.util.ReflectionUtil.getCallerClass(ReflectionUtil.java:128)
    at org.apache.logging.log4j.util.ReflectionUtil.getCallerClass(ReflectionUtil.java:205)
    at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:42)
    at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:42)
    at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:329)
    at org.apache.logging.slf4j.SLF4JLoggerContext.getLogger(SLF4JLoggerContext.java:42)
    at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:37)
    at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:29)
    at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:48)
    at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:329)
    [... more of the same]

I am using Log4j 2 version 2.5 along with SLF4J version 1.7.18.

EDIT: This is my class path:

// JRE 1.8.0_74

// Log4j 2
log4j-1.2-api-2.5.jar
log4j-1.2-api-2.5-javadoc.jar
log4j-1.2-api-2.5-sources.jar
log4j-api-2.5.jar
log4j-api-2.5-javadoc.jar
log4j-api-2.5-sources.jar
log4j-core-2.5.jar
log4j-core-2.5-javadoc.jar
log4j-core-2.5-sources.jar
log4j-core-2.5-tests.jar
log4j-flume-ng-2.5.jar
log4j-flume-ng-2.5-javadoc.jar
log4j-flume-ng-2.5-sources.jar
log4j-iostreams-2.5.jar
log4j-iostreams-2.5-javadoc.jar
log4j-iostreams-2.5-sources.jar
log4j-jcl-2.5.jar
log4j-jcl-2.5-javadoc.jar
log4j-jcl-2.5-sources.jar
log4j-jmx-gui-2.5.jar
log4j-jmx-gui-2.5-javadoc.jar
log4j-jmx-gui-2.5-sources.jar
log4j-jul-2.5.jar
log4j-jul-2.5-javadoc.jar
log4j-jul-2.5-sources.jar
log4j-nosql-2.5.jar
log4j-nosql-2.5-javadoc.jar
log4j-nosql-2.5-sources.jar
log4j-slf4j-impl-2.5.jar
log4j-slf4j-impl-2.5-javadoc.jar
log4j-slf4j-impl-2.5-sources.jar
log4j-taglib-2.5.jar
log4j-taglib-2.5-javadoc.jar
log4j-taglib-2.5-sources.jar
log4j-to-slf4j-2.5.jar
log4j-to-slf4j-2.5-javadoc.jar
log4j-to-slf4j-2.5-sources.jar
log4j-web-2.5.jar
log4j-web-2.5-javadoc.jar
log4j-web-2.5-sources.jar

// SLF4J 1.7.18
slf4j-api-1.7.18.jar
like image 976
Eleno Avatar asked Mar 13 '16 13:03

Eleno


People also ask

What is the difference between log4j and log4j2?

Community support: Log4j 1. x is not actively maintained, whereas Log4j 2 has an active community where questions are answered, features are added and bugs are fixed. Automatically reload its configuration upon modification without losing log events while reconfiguring.

How do I use log4j 2?

There are many ways to use Log4j2 configuration in you application. Using a configuration file written in XML, JSON, YAML or properties file. Programmatically, by creating a configuration factory and configuration implementation. Programmatically, by calling APIs exposed in the configuration interface.


2 Answers

You have more jars than you need. In particular, your application is not using SLF4J, so you don't need to include it. But you have also included log4j-slf4j, log4j-core and log4j-slf4j-impl. Log4g-core is the actual Log4j 2 implementation. log4j-to-slf4j is an implementation of the Log4j 2 API that routes all events to SLF4J. log4j-slf4j-impl will then route the requests back to the Log4j api and the loop will start all over again.

You cannot have both the log4j-to-slf4j and log4j-slf4j-impl jars in the classpath. If you want Log4j 2 to do your logging then remove log4j-to-slf4j.

Also, your sample application is not a web application so you should not have log4j-web in the classpath.

Finally, unless you really want all the optional components like flume, no-sql, and jmx you should not include them.

like image 90
rgoers Avatar answered Oct 21 '22 00:10

rgoers


Obviously your classpath is polluted, these 2 can not be there at same time:

log4j-slf4j-impl-2.5.jar
log4j-to-slf4j-2.5.jar

https://logging.apache.org/log4j/2.0/log4j-slf4j-impl/index.html

Use of the Log4j 2 SLF4J Binding (log4j-slf4j-impl-2.0.jar) together with the SLF4J adapter (log4j-to-slf4j-2.0.jar) should never be attempted, as it will cause events to endlessly be routed between SLF4J and Log4j 2.

Detailed explanation here:

http://www.slf4j.org/legacy.html

like image 43
rkosegi Avatar answered Oct 21 '22 02:10

rkosegi