Sometimes NoClassDefFoundError can be confused with ClassNotFoundException. Both of them are runtime problems but NoClassDefFoundError indicates to us that there was a class at compile time and that class is missing at run time.
Missing class may be caused by different reasons. As the first step, we need to find the library of the class causing NoClassDefFoundError.
Let’s examine a real stack trace for NoClassDefFoundError. This trace tells us org.apache.commons.logging.LogFactory class is missing in the run time.
java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory at org.springframework.core.io.support.SpringFactoriesLoader.(SpringFactoriesLoader.java:58) at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:368) at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:359) at org.springframework.boot.SpringApplication.initialize(SpringApplication.java:230) at org.springframework.boot.SpringApplication.(SpringApplication.java:206) at org.springframework.boot.SpringApplication.run(SpringApplication.java:961) at org.springframework.boot.SpringApplication.run(SpringApplication.java:950) at com.baselayer.dal.core.Application.main(Application.java:20) … 6 more Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory at java.net.URLClassLoader$1.run(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) … 14 more
To locate the jar of a class, you can open it in your IDE and show the .class file in Project Explorer. How you open the file in Project Explorer depends on the editor. In Eclipse, you can click two-way arrows button. In IntelliJ IDEA, you can click crosshair button. Both IDEs show that LogFactory.class is located in commons-logging-1.2.jar.
We have solved part of the problem. Now we need to find out why commons-logging-1.2.jar is missing in run-time environment.
A brief info about application servers
After you develop a Java web application, you need to deploy your application to an application server (like Tomcat, WildFly, Jetty, GlassFish). You can deploy multiple applications on the same server, so usually there is a folder to store common libraries. Shared libraries like logging, DB connection, XML parsing are stored in this folder.
You might also have some application specific libraries. You can store these jar files under /WEB-INF/lib folder of your application.
Let’s take a look at the pom.xml (Maven build file). In pom.xml, commons-logging is defined as provided scope. Provided means, this library is provided in the deployed application server, so Maven build will not include commons-logging-1.2.jar in the deployment file (.war file).
<dependencies> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> <scope>provided</scope> </dependency> ... <dependencies>
This explains why we are getting NoClassDefFoundError. commons-logging-1.2.jar should be missing in application server’s common libraries folder. You can copy this jar to common libraries folder, because all deployed applications will most likely need logging. Alternatively, you can delete the line
<scope>provided</scope> in pom.xml, so Maven build will include this jar in deployment file.
There may be different scenarios. However, in any case NoClassDefFoundError points to a missing class (*.jar) in run-time. To fix the problem, the missing .jar file should be found.