带有 slf4j 和 log4j 的休眠 3.4

Posted

技术标签:

【中文标题】带有 slf4j 和 log4j 的休眠 3.4【英文标题】:Hibernate 3.4 with slf4j and log4j 【发布时间】:2010-10-02 20:16:31 【问题描述】:

我正在尝试从 Hibernate 3.2 升级到 3.4,它显然使用了 slf4j。我们的项目目前使用 log4j。所以我的假设是我应该使用 slf4j-log4j12 包装的实现。

Maven slf4j 依赖是:

<dependency>
    <groupId>org.slf4j</groupId>
     <artifactId>slf4j-log4j12</artifactId>
    <version>1.5.6</version>
</dependency>

虽然 log4j 依赖是:

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.15</version>
</dependency>

slf4j-log4j12 和 log4j 都引用了最新版本(我可以在 Maven 存储库中找到)。当我运行我的应用程序时,Hibernate 的日志记录失败:

java.lang.NoSuchFieldError: name
    at org.slf4j.impl.Log4jLoggerAdapter.<init>(Log4jLoggerAdapter.java:75)
    at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:75)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:103)
    at org.hibernate.cfg.Configuration.<clinit>(Configuration.java:163)
    ...

我错过了什么?

编辑 1: 如果我从 pom.xml 中删除 log4j 依赖项,则会收到错误消息:

java.lang.IllegalAccessError: tried to access field org.slf4j.impl.StaticLoggerBinder.SINGLETON from class org.slf4j.LoggerFactory
    at org.slf4j.LoggerFactory.<clinit>(LoggerFactory.java:60)
    at org.hibernate.cfg.Configuration.<clinit>(Configuration.java:163)
    ...

编辑 2:This blog 声称该问题是由带有错误版本的 slf4j-api.jar 的休眠注释引起的。

【问题讨论】:

休眠 3.4?这篇文章来自未来吗? 【参考方案1】:

我没有问题

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.3.1.GA</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-annotations</artifactId>
        <version>3.4.0.GA</version>
    </dependency>

     <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.5.6</version>
    </dependency>
    <!-- concrete Log4J Implementation for SLF4J API-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.5.6</version>
    </dependency>

【讨论】:

非常感谢,包括依赖关系非常有帮助。【参考方案2】:

这个问题由 SLF4J 常见问题解答。请看

http://slf4j.org/faq.html#compatibility 和 http://slf4j.org/faq.html#IllegalAccessError

【讨论】:

【参考方案3】:

我认为您需要从每个 Hibernate 依赖项中排除内置的 SLF4J 依赖项。

我使用 Hibernate 和 JPA,所以我的配置并不相同,但我认为关键是明确包含 log4j 和 SLF4J 并明确排除所有 org.hibernate 依赖项中的 slf4j-api:

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.15</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>com.sun.jmx</groupId>
                <artifactId>jmxri</artifactId>
            </exclusion>
            <exclusion>
                <groupId>javax.jms</groupId>
                <artifactId>jms</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.sun.jdmk</groupId>
                <artifactId>jmxtools</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-annotations</artifactId>
        <version>3.4.0.GA</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </exclusion>
        </exclusions>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>3.4.0.GA</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </exclusion>
        </exclusions>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.5.6</version>
        <scope>runtime</scope>
    </dependency>

【讨论】:

【参考方案4】:

在检查 slf4j-log4j(然后是 slf4j-parent)的 1.5.6 POM 版本后,您应该使用 log4j-1.2.14。 slf4j-log4j POM 使用依赖管理从 slf4j-parent POM 继承适当版本的 log4j。

但是,您不应该将 log4j 作为特定依赖项包含在内,因为它已经是 slf4j-log4j 的依赖项。那可能是你造成问题的地方。

【讨论】:

从我的 pom.xml 文件中删除 log4j 时,我得到一个不同的错误(见上文)。【参考方案5】:

Google 搜索发现:

http://marc.info/?l=slf4j-user&m=122218775201271&w=2

也许您应该检查您的 JAR 版本以确保它们兼容。

【讨论】:

【参考方案6】:

我在 displaytag 1.2 版(包括旧的 slf4j)上遇到了同样的问题。更改显示标签以排除:

<dependency>
  <groupId>displaytag</groupId>
  <artifactId>displaytag</artifactId>
  <version>1.2</version>
  <exclusions>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl104-over-slf4j</artifactId>
    </exclusion>
  </exclusions>
</dependency>

并添加正确的依赖项:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.5.6</version>
</dependency>
<!-- concrete Log4J Implementation for SLF4J API-->
<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-log4j12</artifactId>
   <version>1.5.6</version>
</dependency>

似乎解决了问题。

【讨论】:

以上是关于带有 slf4j 和 log4j 的休眠 3.4的主要内容,如果未能解决你的问题,请参考以下文章

slf4j 怎么调用 log4j

log4j和slf4j的使用

将项目从 log4j 迁移到 slf4j+log4j

log4j+slf4j管理日志项目迁移logback+slf4j

Log4j 2 + Slf4j 的配置和使用

Log4j2/Slf4j 和 Java 11