简体   繁体   中英

How to bind SLF4J with Log4J?

I am trying to setup a project with slf4j + log4j, but the damn thing just doesn't work... I keep getting exception:

Failed to instantiate SLF4J LoggerFactory
Reported exception:
java.lang.NoClassDefFoundError: org/apache/log4j/Level
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:129)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:108)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:302)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:276)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:288)
at TestLog.main(TestLog.java:9)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Level
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 6 more
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Level
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:129)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:108)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:302)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:276)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:288)
at TestLog.main(TestLog.java:9)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Level
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 6 more

I checked and the class org.apache.log4j.Level is there in my project under "Maven Dependencies > log4j-1.2.17.jar". So why can't the VM find it?

I tried the below options already:

  1. slf4j-api + log4j
  2. slf4j-api + slf4j-log4j12
  3. slf4j-api + log4j
  4. slf4j-api + slf4j-log4j12 + log4j

None of the options worked :(

Here is my currnet pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.sample</groupId>
  <artifactId>DBUnitSample</artifactId>
  <version>1.0</version>

  <dependencies>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.7</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.7</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>

  </dependencies>

</project>

Also, I noticed that when adding slf4j-log4j12, it adds log4j as a dependency as well in the tree, so I am guessing that adding log4j explicitly here is redundant, but I have added it anyway. Still no luck.

My main code is pretty simple:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SampleDao {
    private static final Logger log = LoggerFactory.getLogger(SampleDao.class);

    public static void main(String[] args) {
        System.out.println("Hello");
        log.info("Logged");
    }
}

And my log4j.properties:

log4j.rootLogger=DEBUG, STDOUT
log4j.logger.deng=INFO
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

Can someone please tell me what am I doing wrong? I already tried searching for answers on SO, but all answers mentioned to add log4j dependency, which I have already added... So not sure, whats wrong.

EDIT : Here is my entire project structure. I am R-clicking SampleDao and running it as Java application. ( I have also removed dbunit dependency for now, to zero-in on the slf4j problem) Maven项目结构

Try these dependencies

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.5</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>1.7.5</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.5</version>
    <scope>runtime</scope>
</dependency>

Do you still get the error if you run mvn compile exec:java -D"exec.mainClass"=SampleDao from the command line? I see the following on the command line after running this command, with Maven 3.1.1 on my machine and your code:

Hello
 INFO [SampleDao.main()] (SampleDao.java:9) - Logged

So, your POM and code seem to be fine. It looks like something is wrong with how you are trying to run the code.

Also note that the following simplified configuration should work:

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

You would have to specify a particular version of Log4j if the POM has other dependencies that add different versions of Log4j to the project.

I met the same mistake as you. I solved my problem according to the following two Suggestions.I hope it helps.

1. Modify your pom file:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.2</version>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.12</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.2</version>
</dependency>

2. Add the jar to your startup script

java -cp ./lib/log-producer-1.0.4-SNAPSHOT.jar:./lib/slf4j-log4j12-1.7.2.jar:./lib/slf4j-api-1.7.2.jar:./lib/log4j-1.2.12.jar cn.tiakon.core.Bootstrap

Use this depedences.

<dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.30</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.30</version>
    </dependency>

Config file:

src/main/resources/log4j.properties

Add below dependency :

<dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${logback.version}</version>
        </dependency>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM