Command Line and IDE Development Environments
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 Multi-File Programs Get Packed Into One File
A small Java program may fit in a single class file, but a real program is usually spread across many files. Once that happens, the program becomes awkward to hand over. Someone receiving it would need every class file and every resource file, and they would need to keep all of them in the right places. Java solves this with 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.
This article follows one question through the whole process: what has to be true about a jar file for it to run directly? Keep that question in mind as you read. You will see that the answer depends on a single decision, and that the same decision appears whether you build the jar on the command line or in an IDE.
What a Jar File Contains and How It Runs
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.
The source describes two properties that a jar can have. The first is that a jar can hold many classes and resource files together. The second is that the program can then be run directly from that jar, without unpacking it first. A jar that can be started this way is called an executable jar. It specifies the class that contains the main() routine to run when the jar is executed.
If an executable jar needs no resources beyond what it already contains, it can be started from the command line with the java command and the -jar option. The source also notes that you may be able to start such a jar by double-clicking its icon in a file browser window. A jar that is not executable needs one more piece of information at launch time: the name of the class that contains the main program, added to the end of the same command.
Regular Jar Versus Executable Jar
Both kinds of jar hold classes and resource files, and both can be built with either the command line or an IDE. The difference lies in what the jar tells the Java runtime about where to begin. A regular jar leaves that choice to whoever launches it, so the main class must be named on the launch command. An executable jar records the entry point inside the build, so the launch command can be shorter.
Reading the Jar Command Piece by Piece
On the command line, the jar program comes with the Java Development Kit. Two forms of the command matter here. The regular form is jar cf JarFileName.jar *.class, and the executable form is jar -c -f JarFileName.jar -e MyMainClass *.class. Both are shown exactly as the source gives them.
- Regular jar: the options are written together as cf
- Executable jar: the options are spelled out, and -e names the entry point
Read the executable command from left to right. The first two options set the mode and the output name: -c means create, and -f names the jar file that will be written. The -e option names the entry point, and its value is the full name of the class to run when the jar is executed. The final argument collects the class files. The source states that the -c option means create and that -f names the jar file that will be written. Together with -e and the file list, those pieces make up the whole command. The executable version adds -e and spells out the options, but the rest of the pattern is the same as the regular form.
- jar: the program that builds the archive
- -c: create a new jar
- -f
JarFileName.jar: the file that will be written - -e MyMainClass: the full name of the class that holds
main() - *.class: the class files to put into the jar
How the Manifest Points to the main() Class
The -e option is the bridge between the build command and the launch. When you build an executable jar, the entry point you name becomes part of the jar. The Eclipse export screen labels this part Jar Manifest Specification, and it asks for the Main class. The manifest is the piece of the jar that holds this information, so the launch step can find the right class without being told again.
Follow the flow in the diagram. The launch command gives the jar. The jar's manifest names the class holding main(). That class's main() routine is what runs. The learner-visible consequence is that a regular jar makes you repeat the class name at launch, while an executable jar removes that need because the name is already inside the build.
Building a Jar in an IDE
The way you create a jar depends on your programming environment. The source names two basic routes: the command line and the IDE, an Integrated Development Environment. Any Java IDE should have a command for creating jar files. The source walks through Eclipse as its example, and the steps below follow that description.
- 1In Eclipse, choose Export from the File menu.
- 2Choose JAR file as the export destination.
- 3Enter a path ending in .jar for the file to be created.
- 4For a regular jar, finish the export without naming a main class.
- 5For an executable jar, enter the Main class on the Jar Manifest Specification screen before finishing.
Worked Example: Packaging a Multi-Package Program
Building an executable jar for a program with packages
A program has a main class game.Main in a package called game, and it has a second package called graphics. Build an executable jar named Game.jar that starts from game.Main and includes the class files in both package directories.
- 1Identify the entry point
The -e option takes the full class name, so the value is game.Main, including its package name. Writing only Main would not be the full name.
- 2Choose the mode and output name
Use -c to create the jar and -f
Game.jarto name the file that will be written. - 3List the class files from each package directory
Classes in packages need their subdirectory paths listed, so one wildcard path collects class files from the game directory and another collects them from the graphics directory. On Windows the separator is a backslash, while other systems use a forward slash.
- 4Assemble the command
Combine the pieces: the mode and output name first, then -e with the entry point, then the two wildcard paths. Check each piece against the rules before you run it.
jar -c -f Game.jar -e game.Main game/*.class graphics/*.class
- -c and -f
Game.jarset the mode and output name - -e game.Main is the full class name including the package
- game/*.class and graphics/*.class collect each package directory
Mistakes That Break a Jar
Common mistake Leaving out -e when building an executable jar
What it looks likejar -c -f Game.jar *.class when you wanted the jar to start from game.Main
Why it failsWithout -e, the jar does not name the class holding
main(), so it is not an executable jar.Do this insteadAdd -e with the full class name, for example -e game.Main.
Common mistake Giving only the short class name after -e
What it looks like-e Main for a class that lives in the game package
Why it failsThe source says -e takes the full class name.
Do this insteadWrite the full name, such as game.Main.
Common mistake Forgetting the subdirectory path for classes in packages
What it looks likejar -c -f Game.jar -e game.Main *.class with the classes still in game and graphics directories
Why it failsThe wildcard in the current directory does not reach class files inside subdirectories, so those classes are not collected.
Do this insteadList each package directory, such as game/*.class and graphics/*.class.
Common mistake Using the wrong separator for the operating system
What it looks likeWriting a forward slash in a path on Windows
Why it failsThe source says separators must be adjusted for the operating system.
Do this insteadUse a backslash on Windows and a forward slash on other systems.
Common mistake Assuming a file is in the jar without checking the file list
Finding Where the Build Went Wrong
When a jar does not behave as expected, the useful question is where in the process the result diverged. Instead of rereading the whole command at once, check it against two checkpoints, in order.
- 1Checkpoint one: did the build step produce a jar that contains the files you meant to include? Compare the file list in the command with the files you expected.
- 2Checkpoint two: does the jar run the way you expected? Check whether the launch behaves correctly, and compare the command you ran against the rules in this article.
- 3If the jar will not run directly, look for a missing -e, which points to the executable step.
- 4If a file is missing from the jar, look at the file list, which points to the wildcard paths you gave.
- 5If a class in a package is missing, look for a missing subdirectory path, which points to the packages.
Working through these checkpoints in order tells you the stage where the mismatch began. The first checkpoint separates a packaging problem from a launch problem, and the later checks narrow down which piece of the command is responsible.
Practice: Tracing a Faulty Jar Command
A teammate runs jar -c -f Game.jar *.class to package a program whose main class is game.Main and whose classes sit in a game directory. Launching the jar with java -jar Game.jar fails to start the program. Using the two checkpoints, identify which piece of the command is missing, and write the corrected command.
Hints
- Start with the executable step: does the command tell the jar which class holds
main()? - Remember that -e takes the full class name, including the package.
- Check whether the wildcard reaches the classes inside the game directory.
Key Takeaways
- 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. - On the command line, jar cf creates a regular jar, and jar -c -f
JarFileName.jar-e MyMainClass *.class creates an executable one; -c means create, -f names the file, and -e gives the full class name. - In an IDE such as Eclipse, the same choice is made through Export, JAR file, a .jar path, and a Main class entered on the Jar Manifest Specification screen.
- When a jar misbehaves, check the build against what it should contain, then check whether it runs as expected, working through the pieces of the command one at a time.