Running Java Programs From the Command Line
A jar file packs Java classes and resource files into one archive, and an executable jar names the class with the main() routine to run.
Why Programs Get Packed Into a Jar
Once a program is spread across several files, it becomes awkward to hand over. Java classes and resource files are often distributed together in a single archive called a jar file, short for java archive. A jar file can hold many classes and resource files at once, so a multi-file program can be packed into one file. The program can then be run directly from that jar, without unpacking it first.
What do you think happens?
A jar file contains a class with a main() routine, but the jar is not marked as executable. What extra information must you give when you start it with java -jar?
Reveal answer
The name of the class that contains the main program, added to the end of the command.
A jar that is not executable does not record which class holds main(), so the class name has to be supplied on the command line. An executable jar already names that class, so the command needs nothing extra.
Executable Jars Versus Regular Jars
A jar file can be executable, which means it specifies the class that contains the main() routine to run when the jar is executed. If the jar is executable and needs no resources beyond what it already contains, it can be started from the command line with a short command that names only the jar. The source adds that you may even be able to start such a jar by double-clicking its icon in a file browser window.
- java starts the Java runtime
- -jar tells it to run the program stored in the named jar
JarFileName.jaris the jar whose designated main class is started
A jar that is not executable needs one more piece of information: the name of the class that contains the main program, added to the end of the same command. The difference between the two kinds of jar therefore decides whether a main class has to be named at build time, and it also decides what you must type later to start the program.
Reading the jar Command Piece by Piece
The jar program comes with the Java Development Kit, and the command-line route to a jar uses it directly. Consider the executable form the source gives. Each piece of the command has a specific job, and you can say what each part contributes once you separate them. The first two options set the mode and the output name. The -e option names the entry point. The file list at the end collects the class files to put into the jar.
- jar: the program from the Java Development Kit
- -c: create a new jar
- -f
JarFileName.jar: the name of the jar file that will be written - -e MyMainClass: the entry point, the full name of the class holding
main() - *.class: the class files to collect into the jar
Compare this with the earlier non-executable form, jar cf JarFileName.jar *.class. The executable version adds -e and spells out the options, but the rest of the pattern is the same. Reading the two side by side is a good habit: whatever differs between them is what changes the result.
Building Both Kinds of Jar Step by Step
Building a regular jar and an executable jar from the same classes
You have compiled class files in the current directory, including MyMainClass.class, and you want one jar that can be shared as a plain archive and another that can be started directly with java -jar.
- 1Build the regular jar
Use the form jar cf
JarFileName.jar*.class. The c option creates the jar and f names the output file. No main class is named, so the result is not executable. - 2Build the executable jar
Add -e followed by the full class name: jar -c -f
JarFileName.jar-e MyMainClass *.class. The -e option records the class holdingmain(), which makes the jar executable. - 3Start the executable jar
Run java -jar
JarFileName.jar. The command names only the jar because the entry point was stored at build time. - 4Check the regular jar
Starting the regular jar the same way does not give the JVM a main class to run. You must add the class name to the end of the command, as the source describes for jars that are not executable.
The same class files produce two different jars. Only the one built with -e can be started without naming the main class.
When the class with main() sits inside a package, the -e option still takes the full class name, and the class files in that package must be listed too. The package's subdirectory path appears in the file list, with separators adjusted for the operating system. The example below is an illustration of this rule rather than a command from the source.
- -e shop.app.Main gives the full class name, package included
- shop/app/ is the subdirectory holding the package classes; on Windows the separator is a backslash
- shop/model/ is a second package that must also be listed
IDE Export Versus the jar Command
The way you create a jar file depends on the programming environment you use. Any Java IDE should have a command for creating jar files. In Eclipse, you create a jar through Export, choosing JAR file, entering a .jar path, and, for an executable jar, entering a Main class on the Jar Manifest Specification screen. Both routes can produce a regular jar or an executable jar, and the choice between the two is what determines whether a main class has to be named.
| Question | IDE export (Eclipse example) | jar command |
|---|---|---|
| How is the output file named? | Enter a .jar path in the export wizard | Use -f followed by the jar name |
| How is the main class given? | Enter a Main class on the Jar Manifest Specification screen | Use -e followed by the full class name |
| Which files are included? | Chosen through the export dialog | Listed at the end of the command, such as *.class |
| Kind of jar produced | Regular or executable, chosen in the export | Regular without -e, executable with -e |
The same two decisions, the output name and the main class, appear in both routes.
Mistakes That Break a Jar Build
Most problems with jar files come from a small set of errors. The items below follow the rules the source states, so each correction traces back to something the source says must be true.
Common mistake Leaving out -e and expecting the jar to start
What it looks likejar cf App.jar *.class followed by java -jar App.jar
Why it failsWithout -e the jar does not name the class holding
main(), so the JVM has no entry point.Do this insteadAdd -e with the full class name at build time, or name the main class at the end of the run command for a jar that is not executable.
Common mistake Giving only the simple class name after -e when the class is in a package
What it looks like-e Main for a class whose full name is shop.app.Main
Why it failsThe source says -e takes the full class name.
Do this insteadWrite the full name, such as shop.app.Main.
Common mistake Forgetting the subdirectory paths for packaged classes
What it looks likejar cf Shop.jar *.class when the classes live in shop/app/ and shop/model/
Why it failsClasses in packages need their subdirectory paths listed. A wildcard in the current directory does not reach them.
Do this insteadList each package directory, such as shop/app/*.class, using separators that suit the operating system.
Common mistake Assuming a file is in the jar because the command ran without error
Why it failsThe command can finish while the file list left out the files you intended.
Do this insteadCheck the contents of the jar against the file list you meant to build.
Finding Where a Build Went Wrong
When a jar does not behave as expected, the useful question is where in the process the result diverged. There are two checkpoints. First, did the build step produce a jar that contains the files you meant to include? Second, does the jar run the way you expected? Working through these checkpoints in order tells you the stage where the mismatch began. Checking piece by piece is more reliable than rereading the whole command at once, because each option or argument maps to one part of the result.
Read the flowchart as a sequence of questions. A file missing from the jar points to the file list. A missing subdirectory path points to the packages. A jar that is built but does not start, with nothing listed as missing from the jar, points to the executable step, which in the source is the -e option.
Practice: Diagnose a Jar Build
You run jar cf Report.jar *.class in a project whose main class is app.Launcher, stored in the app subdirectory. After building, java -jar Report.jar fails to start, and the program reports that the main class cannot be found. Which checkpoint did the build diverge at, and what command would you write instead?
Hints
- Ask first whether the jar is executable. Does the command contain -e?
- The class lives in a package, so the source says its full name and subdirectory path must appear in the build.
- A correct executable build uses -c, -f, -e with the full class name, and the file list including app/*.class.
Key Takeaways
- A jar file packs many Java classes and resource files into one archive, so a multi-file program can be shared and run as a single file.
- An executable jar names its main class at build time with -e and the full class name, so it can be started with java -jar and no extra argument.
- Each part of a jar command has a job: the mode, the output file, the entry point, and the file list, and each can be checked separately.
- An IDE export and the jar command both produce regular or executable jars; the difference is the interface, not the result.
- When a jar misbehaves, check first whether it contains the intended files, then whether it starts, to locate the step where the build diverged.