Log4j StackOverflowError

时间:2018-09-12 09:40:37

标签: java log4j

项目启动后,我的项目中立即出现StackOverFlowError。我看到了其他类似的问题,答案是lg4j.xml没有指定或格式不正确,但是这里似乎不是这样。这是代码:

public static void main( String[] args )
{
    // Configure Logger
    DOMConfigurator.configure("config/log4j.xml");

    logger.info("Starting StudyImporter");
}

这是log4j.xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern"
               value="%d{yyyy-MM-dd HH:mm:ss,SSS} - [%t] %-5p %c %x - %m%n" />
    </layout>
</appender>

<!-- log all logs to a separate log file every day -->
<appender name="MAIN_FA" class="org.apache.log4j.DailyRollingFileAppender">
    <param name="File" value="C:/project/logs/main.log" />
    <param name="datePattern" value="'-'yyyy-MM-dd'.log'" />
    <param name="append" value="true" />
    <!-- <param name="Threshold" value="INFO" /> -->
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d [%t] %-5p %C{6} (%F:%L) - %m%n" />
    </layout>
</appender>


<logger name="org.importadorestudios">
    <level value="INFO" />
</logger>

<root>
    <level value="INFO" />
    <appender-ref ref="CONSOLE" />
    <appender-ref ref="MAIN_FA" />
</root>

这是错误:

java.lang.StackOverflowError
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:39)
at org.apache.log4j.LogManager.getLogger(LogManager.java:45)
at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:64)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:285)
at org.apache.log4j.Category.<init>(Category.java:57)
at org.apache.log4j.Logger.<init>(Logger.java:37)
at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:43)
at org.apache.log4j.LogManager.getLogger(LogManager.java:45)
at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:64)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:285)
at org.apache.log4j.Category.<init>(Category.java:57)
at org.apache.log4j.Logger.<init>(Logger.java:37)
at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:43)
at org.apache.log4j.LogManager.getLogger(LogManager.java:45)
at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:64)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:285)
at org.apache.log4j.Category.<init>(Category.java:57)

非常感谢您的帮助

2 个答案:

答案 0 :(得分:2)

问题在于该项目使用的某些库之间存在冲突。

显然,有人曾经使用过另一个我们不再使用的loggin库(slf4j)。我们从pom.xml中删除了该库,但是该库已经在我们的计算机中下载了。这导致冲突,并产生了StackOverflowError。

要解决此问题,只需删除不必要的loggin库。

感谢talex指向正确的方向

答案 1 :(得分:1)

要详细说明我的评论,SLF4J是一个日志记录 facade 。这意味着它所提供的只是一些接口和一些帮助程序类,以使幕后工作变得轻松。要真正使用,您需要选择一个日志记录实现

有许多实现方式可供选择,但最值得注意的是:

选择实现时,通常还需要从SLF4J到该实现的绑定和从其他日志记录API到SLF4J的 bridge 。这些桥接器的存在是使用SLF4J的最大原因,因为您可以将自己的所有应用程序及其依赖项的路由都路由到一个实现中。甚至还支持java.util.logging转发到SLF4J。

但是,关键点是您不能同时在类路径上具有相同实现的绑定和桥接。否则,您将得到在这里看到的结果:堆栈溢出,因为网桥正在调用SLF4J,而SLF4J在调用绑定在调用桥。不幸的是,生态系统和陷阱并非总是被广泛理解,有时人们在分发软件时做错了事。例如,已发布的库永远都不应拉入绑定或桥接。库仅应依赖SLF4J API。仅仅是完成的应用程序或库的测试用例,应该选择一个实现,并因此(如有必要)引入绑定并为其他日志记录API桥接。

这些是绑定:

这些是桥梁:

由于logback的“本机” API与SLF4J重叠,因此没有logback桥。

使用SLF4J时,您想选择一种实现。然后,您包括所有以下内容:

  • slf4j-api
  • 您选择的实现的绑定
  • 所有桥接器 一个用于您选择的实现的桥梁

如果您的任何传递性依赖项尝试将它们引入,则您要排除以下所有项:

  • 您选择的实施的桥梁
  • 任何绑定除了用于您选择的实现的一个

您可以在MavenGradle中设置排除项。