简体   繁体   中英

Java Classpath NoClassDefFoundError During Runtime

I am coming back to Java after quite some time. Having a little trouble with classpath. Would really appreciate it if someone could please point me in the right direction!

My folder structure is as follow:

├── lib
│   └── algs4.jar
└── src
    └── HelloWorld.java

HelloWorld.java

import edu.princeton.cs.algs4.StdOut;

public class HelloWorld {
  public static void main(String[] args) {
    StdOut.println("Hello World");
  }
}

I compiled my program with the following cmd

cd src
javac -cp ../lib/* HelloWorld.java

However, when I run my program using java HelloWorld , I get the following error.

Exception in thread "main" java.lang.NoClassDefFoundError: edu/princeton/cs/algs4/StdOut
        at HelloWorld.main(HelloWorld.java:5)
Caused by: java.lang.ClassNotFoundException: edu.princeton.cs.algs4.StdOut
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

I dont understand how it compiles fine, but then its unable to find classes at runtime. Could someone please shed some light on this? Thank you in advance!

To execute your program you also need to pass the classpath to the java command like this.

java -cp ../lib/* HelloWorld

When you've compiled your code you told the compiler to use the ../lib/* directory(and files) to look up for class definitions, of course, the compiler found them, and write the byte code in the HelloWorld.class file but this bytecode only contains your code (the lines you wrote in HelloWorld.java ) for any external library you use there the compiler will only store a sort of reference with the full package name and the method name. No bytecode from the jar will be stored in the HelloWorld.class file.

So to execute HelloWorld you need to tell the JVM to load first all the external classes that you in the code passing them with the -cp parameter. Then, the JVM will execute your code, look for the reference to the jar code via package/method name and execute them.

If you don't provide -cp../lib/* the JVM will load only the standard library (All the classes in JDK) and your HelloWorld.class thus it won't find the external jar in memory.

It was painful, but I finally fixed it. Turns out when running the program, you not only have to specify the location of the JAR files, but you also have to specify the location of your own file. (Seems obvious now >.<)

For example, in my case, running the following is not good enough.

java -cp ../lib/* HelloWorld

We included the the JARs but didn't include the folder that actually contains HelloWorld.class.

To fix this, I had to run the following. We are including the location of the JAR and the location of the file being executed.

java -cp ../lib/*:. HelloWorld

(Some of you might have to escape * depending on your OS / shell settings)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM