Monday 2 May 2022

How to resolve NoClassDefFoundError?

‘NoClassDefFoundError’ is a linkage error thrown by java runtime, when the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class and no definition of the class could be found.

 


 

Let’s try to produce NoClassDefFoundError and learn how to resolve this error.

 

Define User and App classes.

 

User.java

public class User {

	private int id;
	private String name;

	public User(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + "]";
	}

}

App.java

public class App {
	
	public static void main(String[] args) {
		User user1 = new User(1, "Krishna");
		
		System.out.println(user1);
	}

}

As you see the definition of App.java, it is dependent on User class. When you request JVM to run the App class, Jvm loads all the dependent classes of App class.

 

Let’s compile App class and run.


$ls
App.java	User.java
$
$javac App.java 
$
$ls
App.class	App.java	User.class	User.java

Run App class.

$java App
User [id=1, name=Krishna]

Let’s remove the User.class file and try to run App class.

$rm User.class 
$
$ls
App.class	App.java	User.java
$
$java App
Exception in thread "main" java.lang.NoClassDefFoundError: User
	at App.main(App.java:4)
Caused by: java.lang.ClassNotFoundException: User
	at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	... 1 more

As you see the above snippet, URLClassLoader throws NoClassDefFoundError when it tries to find User class. In most of the cases, this error occur when the class is available at compile time but not at runtime.

 

How to find the root cause and resolve NoClassDefFoundError?

a. Check whether the class is available in classpath or not.

b.   If you know the location of class file, you can resolve this error by explicitly setting the classpath (using -classpath option) while launching the application.

java -classpath path1;path2;...pathN App

For example, let me move User.class file to a folder myClassFiles.
$ls
App.class	App.java	User.class	User.java
$
$mkdir myClassFiles
$
$mv User.class myClassFiles/
$
$tree
.
|____User.java
|____App.java
|____App.class
|____myClassFiles
| |____User.class

 

Run App class.
$java App
Exception in thread "main" java.lang.NoClassDefFoundError: User
	at App.main(App.java:4)
Caused by: java.lang.ClassNotFoundException: User
	at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	... 1 more
 Let’s run App class again by setting the classpath explicitly.

 

$java -classpath .:./myClassFiles/ App
User [id=1, name=Krishna]


c. Sometimes, you might add a dependency with provided scope and expecting that is provided by the environment at run time. This error will occur, when the environment do not provide this dependency at run time.
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>

 


You may like

Interview Questions

instanceof operator behavior with interface and class

Call the main method of one class from other class using reflection

Java: Check whether a class exists in the classpath or not

How to get the name of calling class that invoke given method?

Implement map using array as storage

No comments:

Post a Comment