Thursday, May 18, 2023

How to fix Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory in Java

This error means your code or any external library you are using in your application is using the SLF4J library, an open source logging library, but it is not able to find the required JAR file e.g. slf4j-api-1.7.2.jar hence it's throwing Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory. If you look at the error, you will see that it's saying it is not able to find the class org/slf4j/LoggerFactory or org.slf4j.LoggerFactory. The package name indicates that it's part of SLF4j, hence you need SLF4j JAR files e.g. slf4j-api-1.7.2.jar in your application's classpath. So, go ahead and download the JAR file from SLFj website or from Maven Central repository and restart your application.

Btw, the SLF4j is not really a logging API but it provides abstraction over other logging libraries e.g. Log4j, java.util.logging, or LogBak. It's similar to the commons-logging library but it doesn't mess up like that in a complex environment due to better design.

By using SLF4j, you can switch to any logging library without changing a single line of code in your application e.g. you switch to Log4j from java.util.logging or LogBack.

Hence, apart from SLF4j binaries, you also need proper logging binaries e.g. log4j-1.2.16.jar or logback-1.2.3.jar if you are using LogBack library. Those are the libraries which will be called by SLF4j for doing actual work.

Sometime, you get this error when your code is not really using SLF4j but you are using a tool or library, which internally using it.


For example, I was using log4jdbc.jar, a tool to log SQL statements and their timing while running JDBC code and it give me this error:

Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at net.sf.log4jdbc.Slf4jSpyLogDelegator.<init>(Slf4jSpyLogDelegator.java:45)
at net.sf.log4jdbc.SpyLogFactory.<clinit>(SpyLogFactory.java:37)
at net.sf.log4jdbc.DriverSpy.<clinit>(DriverSpy.java:106)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at Testing.main(Testing.java:15)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 6 more

Since my program was simple and I wasn't really using any Logging API, I was surprised from where does this error came in, but, a quick look to the stack trace suggested that its the net.sf.log4jdbc.DriverSpy class which is using SLF4j for logging.

Later when I read the documentation of log4jdbc, I realize we need both SLF4J and Log4J JAR files to get it working. Since I was running my test program in Eclipse, it was easy for me, I just dropped the slf4j-api-1.7.2.jar and log4j-1.2.16.jar in my project directory. Since it's included in classpath it got picked up easily.

Btw, if you don't know how SLF4j work with different logging library and what JAR files you need to get it working, here is a nice diagram which provides complete overview of how SLF4j works with Lof4j, Java Logging API as well as Logback



Btw, classpath problems are not easy to solve for many Java programmers because they don't know where exactly to put this JAR file to solve their problem. Since every application setup is different, I'll try to cover some scenarios to solve this error.

1. If you are running your Java program using a batch script or shell script, look for -cp or -classpath option and see where it is picking the JAR files. You can put slf4j-api-1.7.2.jar and log4j-1.2.16.jar on those directories.

If you program is running on Linux server, you can simply just do ps -ef | grep java and see the JVM arguments of your Java program to find which directories are in the classpath. If you have access to the script you can also add a new directory to the classpath.

$ ps -ef | grep java
/opt/jre/v1.7.0_80-64bit/bin/java -Xmx8192M -Xms8192M 
-classpath /app/myapp.jar:/app/jackson.jar MyApplication

2. If your program is using CLASSPATH environment variable then you need to just echo $CLASSPATH and put the slf4j-API-1.7.2.jar and log4j-1.2.16.jar files into the directory already present in the CLASSPATH or you can just add a new directory into the CLASSPATH. See this article to know how to make a change in CLASSPATH environment variable.


3. If you are using Eclipse then just drop the slf4j-API-1.7.2.jar and log4j-1.2.16.jar into your project directory. It is by default in the classpath so the JARs will be picked up by your application.



How to download SLF4j and Log4j JAR file

You can either download slf4j-api-1.7.2.jar and log4j-1.2.16.jar from respective websites e.g. https://www.slf4j.org and https://logging.apache.org/log4j/1.2/download.html or just download them from the Maven Central repository.

If you are using Maven for building your project and managing dependencies, you can also add following Maven dependency to download SLF4J and Log4j JAR files into your project:

<!-- SLF4J API -->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.2</version>
</dependency>

<!-- LOG4J -->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.2.16</version>
</dependency>


Once you add these dependencies, make sure you do a clean build from Maven to actually download these dependencies from Maven's remote repository.


That's all about how to fix Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory error in Java. All you need to do is add the slf4j-API-1.7.2.jar and log4j-1.2.16.jar files into your classpath.

The version may differ depending upon individual cases but you must add a compatible version of SLF4J and the logging library you are using. For example, if your application is using LogBack you need to add a relevant version of the logback.jar file.

If you use Maven, you can also download these JAR files by adding relevant dependencies in pom.xml otherwise, you can just download the JAR file from Maven central or directly from SLF4j and Log4j website and add to your application's classpath.

If you find any trouble adding SLF4J and LOG4j JAR files into classpath you can also tell us in the comment section and we can try to help you out.

Other Java troubleshooting Guides you may like
  • How to solve ArrayIndexOutOfBoundsException in Java? (guide)
  • How to solve NullPointerException in Java? (guide)
  • How to solve the "System cannot find the Path specified" error? (solution)
  • How to solve NoClassDefFoundError while running Java program from a command line? (solution)
  • How to solve "No JVM found, Please install 64-bit JDK" error in Android Studio? (solution)
  • How to deal with SQLException "No Suitable driver found " error in JDBC and MySQL? (guide)
  • How to solve NumberFormatException in Java? (guide)
  • How to solve Minecraft - java.lang.UnsatisfiedLinkError: lwjgl64.dll : Access Denied? (solution)
  • How to fix java.lang.ArrayIndexOutOfBoundsException: 1 in Java? (solution)
  • How to fix java.net.SocketException: Software caused connection abort: recv failed (fix)

Thanks for reading this tutorial, if you like this tutorial then please share with your friends and colleagues.  If you have any question or suggestion then please drop a comment.

No comments :

Post a Comment