java - What does "Could not find or load main class" mean? -
a common problem new java developers experience programs fail run error message: could not find or load main class ...
what mean, causes it, , how should fix it?
the java <class-name>
command syntax
first of all, need understand correct way launch program using java
(or javaw
) command.
the normal syntax1 this:
java [ <option> ... ] <class-name> [<argument> ...]
where <option>
command line option (starting "-" character), <class-name>
qualified java class name, , <argument>
arbitrary command line argument gets passed application.
1 - there second syntax "executable" jar files describe @ bottom.
the qualified name (fqn) class conventionally written in java source code; e.g.
packagename.packagename2.packagename3.classname
however versions of java
command allow use slashes instead of periods; e.g.
packagename/packagename2/packagename3/classname
which (confusingly) looks file pathname, isn't one. note term fully qualified name standard java terminology ... not made confuse :-)
here example of java
command should like:
java -xmx100m com.acme.example.listusers fred joe bert
the above going cause java
command following:
- search compiled version of
com.acme.example.listusers
class. - load class.
- check class has
main
method signature, return type , modifiers givenpublic static void main(string[])
. (note, method argument's name not part of signature.) - call method passing command line arguments ("fred", "joe", "bert")
string[]
.
reasons why java cannot find class
when message "could not find or load main class ...", means first step has failed. java
command not able find class. , indeed, "..." in message fully qualified class name java
looking for.
so why might unable find class?
reason #1 - made mistake classname argument
the first cause may have provided wrong class name. (or ... right class name, in wrong form.) considering example above, here variety of wrong ways specify class name:
example #1 - simple class name:
java listuser
when class declared in package such
com.acme.example
, must use full classname including package name injava
command; e.g.java com.acme.example.listuser
example #2 - filename or pathname rather class name:
java listuser.class java com/acme/example/listuser.class
example #3 - class name casing incorrect:
java com.acme.example.listuser
example #4 - typo
java com.acme.example.mistuser
example #5 - source filename
java listuser.java
example #6 - forgot class name entirely
java lots of arguments
reason #2 - application's classpath incorrectly specified
the second cause class name correct, java
command cannot find class. understand this, need understand concept of "classpath". explained well oracle documentation:
- the
java
command documentation - setting classpath.
- the java tutorial - path , classpath
so ... if have specified class name correctly, next thing check have specified classpath correctly:
- read 3 documents linked above. (yes ... read them. important java programmer understands @ least basics of how java classpath mechanisms works.)
- look @ command line , / or classpath environment variable in effect when run
java
command. check directory names , jar file names correct. - if there relative pathnames in classpath, check resolve correctly ... current directory in effect when run
java
command. - check class (mentioned in error message) can located on effective classpath.
- note classpath syntax different windows versus linux , mac os.
reason #2a - wrong directory on classpath
when put directory on classpath, notionally corresponds root of qualified name space. classes located in directory structure beneath root, by mapping qualified name pathname. example, if "/usr/local/acme/classes" on class path, when jvm looks class called com.acme.example.foon
, ".class" file pathname:
/usr/local/acme/classes/com/acme/example/foon.class
if had put "/usr/local/acme/classes/com/acme/example" on classpath, jvm wouldn't able find class.
reason #2b - subdirectory path doesn't match fqn
if classes fqn com.acme.example.foon
, jvm going "foon.class" in directory "com/acme/example":
if directory structure doesn't match package naming per pattern above, jvm won't find class.
if attempt rename class moving it, fail ... exception stacktrace different.
to give concrete example, supposing that:
- you want run
com.acme.example.foon
class, - the full file path
/usr/local/acme/classes/com/acme/example/foon.class
, - your current working directory
/usr/local/acme/classes/com/acme/example/
,
then:
# wrong, fqn needed java foon # wrong, there no `com/acme/example` folder in current working directory java com.acme.example.foon # wrong, similar above java -classpath . com.acme.example.foon # fine; relative classpath set java -classpath ../../.. com.acme.example.foon # fine; absolute classpath set java -classpath /usr/local/acme/classes com.acme.example.foon
notes:
- the
-classpath
option can shortened-cp
in java releases. check respective manual entriesjava
,javac
, on. - think when choosing between absolute , relative pathnames in classpaths. remember relative pathname may "break" if current directory changes.
reason #2c - dependencies missing classpath
the classpath needs include of other (non-system) classes application depends on. (the system classes located automatically, , need concern this.) main class load correctly, jvm needs find:
- the class itself.
- all classes , interfaces in superclass hierarchy (e.g. see java class present in classpath startup fails error: not find or load main class)
- all classes , interfaces referred means of variable or variable declarations, or method call or field access expressions.
(note: jls , jvm specifications allow scope jvm load classes "lazily", , can affect when classloader exception thrown.)
reason #3 - class has been declared in wrong package
it happens puts source code file the wrong folder in source code tree, or leave out package
declaration. if in ide, ide's compiler tell immediately. if use decent java build tool, tool run javac
in way detect problem. however, if build java code hand, can in such way compiler doesn't notice problem, , resulting ".class" file not in place expect be.
the java -jar <jar file>
syntax
the alternative syntax used "executable" jar files follows:
java [ <option> ... ] -jar <jar-file-name> [<argument> ...]
e.g.
java -xmx100m -jar /usr/local/acme-example/listuser.jar fred
in case name of entry-point class (i.e. com.acme.example.listuser
) , classpath specified in manifest of jar file.
ides
a typical java ide has support running java applications in ide jvm or in child jvm. these generally immune particular exception, because ide uses own mechanisms construct runtime classpath, identify main class , create java
command line.
however still possible exception occur, if things behind of ide. example, if have set application launcher java app in eclipse, , moved jar file containing "main" class different place in file system without telling eclipse, eclipse unwittingly launch jvm incorrect classpath.
in short, if problem in ide, check things stale ide state, broken project references or broken launcher configurations.
it possible ide confused. ide's hugely complicated pieces of software comprising many interacting parts. many of these parts adopt various caching strategies in order make ide whole responsive. these can go wrong, , 1 possible symptom problems when launching applications. if suspect happening, worth restarting ide.
other references
- from oracle java tutorials - common problems (and solutions)
Comments
Post a Comment