Java can't find main class

Your class Hello belongs to the package com. So the fully qualified name of your class is com.Hello. When you invoke a program using java on the command-line, you should supply the fully-qualified class name of the class that contains your main method and omit the .class, like so:

java com.Hello

The java program needs this fully-qualified class name to understand which class you are referring to.

But you have another problem. The java program locates packages, sub-packages, and the classes that belong to them using the filesystem. So if you have a package structure like com.Hello, the java program expects to find a class file named Hello.class in a directory named com, like this: com/Hello.class. In fact you can observe this behavior in the Exception that you see; you've incorrectly used Hello.class, which java is interpreting as a package named Hello, and a class named class, and is looking for the directory structure Hello/class:

java.lang.NoClassDefFoundError: Hello/class

But the compiler javac doesn't set up this directory structure by default. See the documentation for javac, but the important bit is this: when you do your compiles, you can specify a destination directory using the -d flag:

-d directory

Set the destination directory for class files. The destination directory must already exist; javac will not create the destination directory. If a class is part of a package, javac puts the class file in a subdirectory reflecting the package name, creating directories as needed. For example, if you specify -d c:\myclasses and the class is called com.mypackage.MyClass, then the class file is called c:\myclasses\com\mypackage\MyClass.class.

If -d is not specified, javac puts the class file in the same directory as the source file.

The last bit in bold is the source of much confusion for beginners, and is part of your own problem.

So you have two alternatives:

  1. In your case, it's fine if you supply the current directory as the destination directory, like so (the period . means current directory):

    javac -d . Hello.java
    

    If you invoke the compiler like this, it will create the com directory for you, and put your compiled class file in it, the way that the java program expects to find it. Then when you run java as above, from c:\tmpJava, your program should execute.

  2. You could set up your source code using a directory structure that mirrors your package structure: put your source file Hello.java inside a directory called com, in your case: c:\tmpJava\com\Hello.java. Now, from c:\tmpJava you can run your javac compile like this:

    javac com\Hello.java
    

    You haven't supplied the -d flag, but that's fine, because you've created the directory structure yourself, and quoting again from the documentation above:

    If -d is not specified, javac puts the class file in the same directory as the source file.

    Again, when you run java as above, your program should execute.

    Note that this second alternative is one that is commonly employed by java programmers: the source code files are organized in a directory structure that mirrors the package structure.

In this explanation we've ignored the concept of the classpath. You'll also need to understand that to write java programs, but in your case of simply compiling a program in the current directory - if you follow one of the two alternatives above when compiling your class - you can get away without setting a classpath because, by default, the java program has the current directory as a classpath. Another quote, this one from the documentation for java:

-cp classpath

Specify a list of directories, JAR archives, and ZIP archives to search for class files. Class path entries are separated by semicolons (;). Specifying -classpath or -cp overrides any setting of the CLASSPATH environment variable.

If -classpath and -cp are not used and CLASSPATH is not set, the user class path consists of the current directory (.).

Note that when you use an IDE like Eclipse to run your java code, this is mostly handled for you, but you'll still run into classpath issues.


The syntax of the Java command is:

java [classname]

not

java [filename]

Java looks in its classpath for a class of the name you have provided. Usually the classpath includes the current directory, so:

java Hello

... will find Hello.class in the current directory, and run its main() method.

However, if the class is somewhere else (like in a .jar, or somewhere else in the filesystem) you can specify it with the CLASSPATH environment variable, or on the commandline:

java -cp build/classes Hello
java -cp build/jars/myjar.jar Hello

The class should be in C:\tmpjava\com\Hello.class
And you should run from C:\tmpjava: java -cp . com.Hello
When you put a class in a package it defines the file structure of the class. I.e. your class which in package com should be in folder com


Run the following command

java -cp . com.Hello