tags:

views:

145

answers:

2

I have a simple Class

package chapter10;

public class CompilationTest {


  public static void main(String[] args) {
    System.out.println("HELLO WORLD");
  }

}

The path is

Test\src\chapter10\CompilationTest.java

I successfully compiled the code into the same folder and now I have

Test\src\chapter10\CompilationTest.class

However when I try to run from the same folder it I get this error

>java CompilationTest


Exception in thread "main" java.lang.NoClassDefFoundError: CompilationTest (wrong name: chapter10/CompilationTest)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(Unknown Source)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$000(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 sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: CompilationTest.  Program will exit.

When I run using

>java chapter10/PropertiesTest

Exception in thread "main" java.lang.NoClassDefFoundError: chapter10/PropertiesTest
Caused by: java.lang.ClassNotFoundException: chapter10.PropertiesTest
        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 sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: chapter10/PropertiesTest.  Program will exit.
+3  A: 

Run using java chapter10.PropertiesTest. The Java command expects the fully qualified Java class name, not the pathname of the bytecode file.

The Java command locates classes to be loaded by looking on the classpath. This is a list of directories or JAR files to be searched in order. The algorithm used is roughly as follows:

  1. Take the fully qualified name of the class, replace "." characters with the applicable file separator character (e.g. "/" or "\"), and append ".class" to the end. The result is a pathname.

  2. For each entry in the classpath, lookup the pathname relative to the entry.

    1. If the lookup succeeds, load the corresponding file.
    2. Otherwise, continue to the next classpath entry.
  3. If no lookup succeeded, throw a ClassNotFoundException.

The classpath can be set using an explicit command line parameter (-cp <path>) or it can be picked up from a CLASSPATH environment variable. If no classpath is set by either of these methods, a default classpath of "." is assumed, where "." denotes the current directory.

As @BalusC says, best practice is to use the "-cp" argument or create a wrapper script to launch your application. Relying on your shell's $CLASSPATH is a bit flakey, because you never know when it might be overridden or reset.

(This is a simplified description. It does not cover "bootclasspath", classpaths set in loadable JAR files, classloading from URLs, how inner/anonymous classes are handled, etc, etc.)

Stephen C
+4  A: 

The class is in the chapter10 package. Run it from the parent directory as:

java chapter10.CompilationTest

The reason for going to the parent is that Java is searching its CLASSPATH, which includes the current directory, for a chapter10 directory containing a CompilationTest.class file. You could also add the src directory's absolute path to the CLASSPATH to achieve the same effect:

set CLASSPATH=C:\...\Test\src
java chapter10.CompilationTest

Or (apparently this is better style) add the -cp or -classpath argument to java:

java -cp "C:\...\Test\src" chapter10.CompilationTest
Marcelo Cantos
Why does java want me to go to the parent directory first?
kunjaan
I've added a clarification to the answer.
Marcelo Cantos
The `CLASSPATH` environment variable is considered bad practice. Rather use `-cp` or `-classpath` argument or just a `.bat`/`.sh` file.
BalusC
Thanks for pointing that out, @BalusC. I've emended the answer.
Marcelo Cantos
Good answer, but it's called a package in Java, not a namespace (although packages are a kind of namespace).
Joachim Sauer
Thanks Joachim. I've amended the answer.
Marcelo Cantos