How to solve java.lang.NoClassDefFoundError?

Jonathan Lam picture Jonathan Lam · Jul 31, 2013 · Viewed 1.1M times · Source

I've tried both the example in Oracle's Java Tutorials. They both compile fine, but at run-time, both come up with this error:

Exception in thread "main" java.lang.NoClassDefFoundError: graphics/shapes/Square
    at Main.main(Main.java:7)
Caused by: java.lang.ClassNotFoundException: graphics.shapes.Square
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    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)
    ... 1 more

I think I might have the Main.java file in the wrong folder. Here is the directory hierarchy:

graphics
├ Main.java
├ shapes
|   ├ Square.java
|   ├ Triangle.java
├ linepoint
|   ├ Line.java
|   ├ Point.java
├ spaceobjects
|   ├ Cube.java
|   ├ RectPrism.java

And here is Main.java:

import graphics.shapes.*;
import graphics.linepoint.*
import graphics.spaceobjects.*;

public class Main {
    public static void main(String args[]) {
        Square s = new Square(2,3,15);
        Line l = new Line(1,5,2,3);
        Cube c = new Cube(13,32,22);
    }
}

What am I doing wrong here?

UPDATE

After I put put the Main class into the graphics package (I added package graphics; to it), set the classpath to "_test" (folder containing graphics), compiled it, and ran it using java graphics.Main (from the command line), it worked.

Really late UPDATE #2

I wasn't using Eclipse (just Notepad++ and the JDK), and the above update solved my problem. However, it seems that many of these answers are for Eclipse and IntelliJ, but they have similar concepts.

Answer

Samuel picture Samuel · Jul 31, 2013

After you compile your code, you end up with .class files for each class in your program. These binary files are the bytecode that Java interprets to execute your program. The NoClassDefFoundError indicates that the classloader (in this case java.net.URLClassLoader), which is responsible for dynamically loading classes, cannot find the .class file for the class that you're trying to use.

Your code wouldn't compile if the required classes weren't present (unless classes are loaded with reflection), so usually this exception means that your classpath doesn't include the required classes. Remember that the classloader (specifically java.net.URLClassLoader) will look for classes in package a.b.c in folder a/b/c/ in each entry in your classpath. NoClassDefFoundError can also indicate that you're missing a transitive dependency of a .jar file that you've compiled against and you're trying to use.

For example, if you had a class com.example.Foo, after compiling you would have a class file Foo.class. Say for example your working directory is .../project/. That class file must be placed in .../project/com/example, and you would set your classpath to .../project/.

Side note: I would recommend taking advantage of the amazing tooling that exists for Java and JVM languages. Modern IDE's like Eclipse and IDEA and build management tools like Maven or Gradle will help you not have to worry about classpaths (as much) and focus on the code! That said, this link explains how to set the classpath when you execute on the command line.