Java.exe is connected to the console while Javaw.exe has no such connection. So while java.exe is running, a command prompt window is automatically opened in which performance and error streams are displayed. … The javaw command is similar to java, except that javaw does not have a console window associated with it.
Entry point classes
A Java entry-point class has a main method with the following signature and modifiers:
public static void main(String[] args)
Sidenote: because of how arrays work, it can also be (String args[])
When the java commands starts the virtual machine, it loads the specified entry-point classes and tries to find the main. If successful, the arguments from command line are converted to Java String objects and assembled into an array. If the main is invoked like this, the array will not be null and won’t contain any null entries.
A valid entry-point class method must do the following:
- Be named main (case-sensitive)
- Be public and static
- Have a void return type
- Have a single argument with an array String[]. The argument must be present and no more than one
- argument is allowed.
- Be generic: type parameters are not allowed.
- Have a non-generic, top-level (not nested or inner) enclosing class
It is conventional to declare the class as public but this not strictly necessary. From Java 5 onward, the main
method’s argument type may be a String varargs instead of a string array. main can optionally throw exceptions,
and its parameter can be named anything, but conventionally it is args.
JavaFX entry-points
From Java 8 onwards the java command can also directly launch a JavaFX application. JavaFX is documented in the JavaFX tag, but a JavaFX entry-point must do the following:
- Extend javafx.application.Application
- Be public and not abstract
- Not be generic or nested
- Have an explicit or implicit public no-args constructor
Troubleshooting the ‘java’ command
This example covers common errors with using the ‘java’ command.
“Command not found”
If you get an error message like:
java: command not found
when trying to run the java command, this means that there is no java command on your shell’s command search
path. The cause could be:
- you don’t have a Java JRE or JDK installed at all,
- you have not updated the PATH environment variable (correctly) in your shell initialization file, or
- you have not “sourced” the relevant initialization file in the current shell.
Refer to “Installing Java” for the steps that you need to take.
“Could not find or load main class”
This error message is output by the java command if it has been unable to find/load the entry-point class that you have specified. In general terms, there are three broad reasons that this can happen:
- You have specified an entry point class that does not exist.
- The class exists, but you have specified it incorrectly.
- The class exists and you have specified it correctly, but Java cannot it find it because the classpath is incorrect.
Here is a procedure to diagnose and solve the problem:
1. Find out the full name of the entry-point class.
- If you have source code for a class, then the full name consists of the package name and the simple
- class name. The instance the “Main” class is declared in the package “com.example.myapp” then its full
- name is “com.example.myapp.Main”.
- If you have a compiled class file, you can find the class name by running javap on it.
- If the class file is in a directory, you can infer the full class name from the directory names.
- If the class file is in a JAR or ZIP file, you can infer the full class name from the file path in the JAR or ZIP file.
2. Look at the error message from the java command. The message should end with the full class name that java is trying to use.
- Check that it exactly matches the full class name for the entry-point class.
- It should not end with “.java” or “.class”.
- It should not contain slashes or any other character that is not legal in a Java identifier1.
- The casing of the name should exactly match the full class name.
3. If you are using the correct class name, make sure that the class is actually on the classpath:
- Work out the pathname that the classname maps to; see Mapping classnames to pathnames
- Work out what the classpath is; see this example: Different ways to specify the classpath
- Look at each of the JAR and ZIP files on the classpath to see if they contain a class with the required
- pathname.
- Look at each directory to see if the pathname resolves to a file within the directory.
If checking the classpath by hand did not find the issue, you could add the -Xdiag and -XshowSettings options. The former lists all classes that are loaded, and the latter prints out settings that include the effective classpath for the JVM.
Finally, there are some obscure causes for this problem:
- An executable JAR file with a Main-Class attribute that specifies a class that does not exist.
- An executable JAR file with an incorrect Class-Path attribute.
- If you mess up2 the options before the class name, the java command may attempt to interpret one of them as the class name.
- If someone has ignored Java-style rules and used package or class identifiers that differ only in letter case, and you are running on a platform that treats letter case in filenames as non-significant.
- Problems with homoglyphs in class names in the code or on the command line.
“Main method not found in class <name> ”
This problem happens when the java command is able to find and load the class that you nominated but is then unable to find an entry-point method.
There are three possible explanations:
- If you are trying to run an executable JAR file, then the JAR’s manifest has an incorrect “Main-Class” attribute that specifies a class that is not a valid entry point class.
- You have told the java command a class that is not an entry point class.
- The entry point class is incorrect; see Entry point classes for more information.
Running a Java application with library dependencies
This is a continuation of the “main class” and “executable JAR” examples.
Typical Java applications consist of an application-specific code, and various reusable library code that you have implemented or that has been implemented by third parties. The latter is commonly referred to as library dependencies, and are typically packaged as JAR files.
Java is a dynamically bound language. When you run a Java application with library dependencies, the JVM needs to know where the dependencies are so that it can load classes as required. Broadly speaking, there are two ways to deal with this:
- The application and its dependencies can be repackaged into a single JAR file that contains all of the required classes and resources.
- The JVM can be told where to find the dependent JAR files via the runtime classpath.
For an executable JAR file, the runtime classpath is specified by the “Class-Path” manifest attribute. (Editorial Note: This should be described in a separate Topic on the jar command.) Otherwise, the runtime classpath needs to be supplied using the -cp option or using the CLASSPATH environment variable.
For example, suppose that we have a Java application in the “myApp.jar” file whose entry point class is com.example.MyApp. Suppose also that the application depends on library JAR files “lib/library1.jar” and “lib/library2.jar”. We could launch the application using the java command as follows in a command line:
$ # Alternative 1 (preferred)
$ java -cp myApp.jar:lib/library1.jar:lib/library2.jar com.example.MyApp
$ # Alternative 2
$ export CLASSPATH=myApp.jar:lib/library1.jar:lib/library2.jar
$ java com.example.MyApp
(On Windows, you would use ; instead of : as the classpath separator, and you would set the (local) CLASSPATH variable using set rather than export.)
While a Java developer would be comfortable with that, it is not “user friendly”. So it is common practice to write a simple shell script (or Windows batch file) to hide the details that the user doesn’t need to know about. For example, if you put the following shell script into a file called “myApp”, made it executable, and put it into a directory on the command search path:
#!/bin/bash
#The 'myApp' wrapper script
export DIR=/usr/libexec/myApp
export CLASSPATH=$DIR/myApp.jar:$DIR/lib/library1.jar:$DIR/lib/library2.jar
java com.example.MyApp
then you could run it as follows:
$ myApp arg1 arg2 …
Any arguments on the command line will be passed to the Java application via the “$@” expansion. (You can do something similar with a Windows batch file, though the syntax is different.)