Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 Project Structure

like image 421
Pat Avatar asked Sep 06 '14 20:09

Pat


People also ask

Can we use log4j and SLF4J together?

So essentially, SLF4J does not replace log4j; they both work together. It removes the dependency on log4j from your application and makes it easy to replace it in the future with the more capable library.

Does SLF4J have dependency on log4j?

logging, logback and reload4j. SLF4J allows the end-user to plug in the desired logging framework at deployment time. Note that SLF4J-enabling your library/application implies the addition of only a single mandatory dependency, namely slf4j-api-2.0.


3 Answers

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>
like image 76
Dmytro Plekhotkin Avatar answered Nov 03 '22 04:11

Dmytro Plekhotkin


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.

like image 20
manish Avatar answered Nov 03 '22 04:11

manish


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
like image 36
kai.tian Avatar answered Nov 03 '22 04:11

kai.tian