有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Log4j堆栈溢出错误

我的项目一启动就会出现StackOverflower错误。我见过其他类似的问题,答案是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) 个答案

  1. # 1 楼答案

    为了详细说明我的评论,SLF4J是一个日志门面。这意味着它所提供的只是一些接口和一些帮助器类,用于在幕后处理问题。要实际使用它,您需要选择一个日志实现

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

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

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

    这些是绑定:

    这些是桥梁:

    因为logback的“本机”API与SLF4J重叠,所以没有logback桥

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

    • slf4j-api
    • 您选择的实现的绑定
    • 除了所选实现的之外的所有桥接

    如果您的任何可传递依赖项试图将它们拉入,您希望排除以下所有内容:

    • 您选择的实现的桥梁
    • 除所选实现的绑定之外的任何绑定

    您可以在MavenGradle中设置排除

  2. # 2 楼答案

    问题是项目使用的一些库之间存在冲突

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

    要解决这个问题,只需删除不必要的loggin库

    感谢talex为我们指明了正确的方向