6

I've been working on this for about an hour and thumbing through Q&As on stackoverflow but I haven't found a proposed solution to my problem. I'm sorry if this is a duplicate, but I couldn't find any duplicate question with an answer that solved my specific problem.

I am trying to write and compile a java program from terminal for the first time (up until this point I have been using Eclipse for java and VIM for everything else, but I feel its time to switch entirely to VIM). Here is my current HelloWorld code:

package main;

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

I compile and run using the following commands (specifying the classpath to ensure that isn't the problem):

javac -cp "./" HelloWorld.java
java -cp "./" HelloWorld

This gives me the following error message:

Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld (wrong name: main/HelloWorld)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    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:423)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:480)

I know it is seeing the file HelloWorld.class and trying to access the class HelloWorld because if I change the run command to:

java -cp "./" Foo

I get an entirely different error message:

Error: Could not find or load main class Foo

I have tried several dozen pages worth of troubleshooting and come up short, including the following:

Exception in thread "main" java.lang.NoSuchMethodError: main

http://introcs.cs.princeton.edu/java/15inout/mac-cmd.html

java -version yields:

java version "1.7.0_07"
Java(TM) SE Runtime Environment (build 1.7.0_07-b10)
Java HotSpot(TM) Client VM (build 23.3-b01, mixed mode)

My operating system is LinuxMint and uname -a yields:

Linux will-Latitude-D620 2.6.38-8-generic #42-Ubuntu SMP Mon Apr 11 03:31:50 UTC 2011 i686 i686 i386 GNU/Linux
Community
  • 1
  • 1
retrohacker
  • 3,194
  • 4
  • 21
  • 31

4 Answers4

24

package main;

This means that your class resides in the main package, and its canonical name is main.HelloWorld.

Java requires that package names should also be mirrored in the directory structure. This means that:

  1. Your HelloWorld.java file should be in a directory named main
  2. You should execute javac and java from the directory containing main, not from main itself
  3. The classpath should contain the directory where the main directory is, not main itself
  4. java expects the canonical name of the class to execute, so main.HelloWorld

So, to recap:

You should have something like myproject/main/HelloWorld.java

From myproject, run javac main/HelloWorld.java

From myproject, run java -cp ./ main.HelloWorld

Sergiu Dumitriu
  • 11,455
  • 3
  • 39
  • 62
  • Thank you sir! You are absolutely correct, my problem was with the filesystem! Coming from eclipse I didn't fully understand the classpath and had my java files in the base directory. Once I created a main folder and moved the source files to this folder, the problem was solved! – retrohacker Jan 03 '13 at 03:39
  • Thanks, this solved my problem too. Just to add to it, people switching from Windows to Linux might experience this problem (?) because I was fine on Windows 7 and moving to Ubuntu raised this error (I think). – Chris Beeley May 26 '13 at 23:15
  • This should give me a file called "main.class" in "myproject" folder or "HelloWorld.class" in "main" folder? – alex Nov 12 '16 at 21:36
  • 1
    @alex A file called `HelloWorld.class` in the `main` folder. – Sergiu Dumitriu Nov 13 '16 at 03:48
10

You've put your class in a package named "main", but you're trying to treat it like it isn't in a package. Since you put package main; at the top of your source file, you need to put HelloWorld.java in ./main, then run javac ./main/HelloWorld.java, followed by java -cp . main.HelloWorld.

These commands will get you the working example you're trying to build:

mkdir main
echo 'package main; public class HelloWorld { public static void main(String... args) { System.out.println("Hello World"); } }' > main/HelloWorld.java
javac main/HelloWorld.java
java -cp . main.HelloWorld
Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
3

As a beginner you might encounter a very similar scenario where the error output is the same. You try to compile and run your simple program(without having any package set) and you do this:

javac HelloWorld.java
java HelloWorld.class

This will give you the same java.lang.NoClassDefFoundError since java thinks HelloWorld is your package and class your class name. To solve it just use

javac HelloWorld.java
java HelloWorld

See the Java page - Lesson: Common Problems (and Their Solutions)

Reed Richards
  • 4,178
  • 8
  • 41
  • 55
0

Problem: Basically, the Exception in thread "main" java.lang.NoClassDefFoundError:

means, that the class which you are trying to run was not found in the classpath.

Solution: you need to add the class or .jar file which contains this class into the java classpath. When you are running a java class from the command line, you need to add the dot (.)

java YourSingleClass -cp .

into the classpath which tells the JVM to search for classes in actual directory.

If you are running a class from a .jar file, you need to add this jar file into the classpath:

java org.somepackage.SomeClass -cp myJarWithSomeClass.jar
Dixit Patel
  • 3,190
  • 1
  • 24
  • 36
  • 1
    The important thing to point out here is actually that he's not specifying the fully qualified classname (in his case `main.HelloWorld`) – Greg Kopff Jan 03 '13 at 03:30
  • Isn't that what I am doing with `javac -cp "./" HelloWorld.java` and `java -cp "./" HelloWorld` ? – retrohacker Jan 03 '13 at 03:30
  • And if I change the run command to `java -cp . main/HelloWorld` I get the `Error: Could not find or load main class main.HelloWorld` error again. – retrohacker Jan 03 '13 at 03:31