Packages and Class Organization in Java
A jar file holds the compiled classes and resource files of a program, but running it still requires Java on the target machine; jpackage bundles a Java virtual machine into an installer to remove that requirement.
Handing a Finished Program to a Friend
Suppose you have finished a Java program and want to give it to a friend. A reasonable first step is to gather the compiled class files and resource files into a single jar file and send that along. The catch is that your friend still needs a Java runtime installed on their machine to run it. For most people that is an unlikely situation, unless they are Java developers themselves. Packaging is the problem of closing that gap, so the person receiving the program does not have to prepare a Java environment first.
The Java Development Kit includes a tool called jpackage that is built for this job. It produces an installer that places your program on a machine together with as much Java support as the program needs. This article follows one concrete case from start to finish, so you can see which step produces which artifact and where things can go wrong.
What do you think happens?
The finished jar in the example is called Poker.jar. What name will the installer that jpackage produces carry?
Reveal answer
netpoker, from the --name option
The installer's name comes from the --name option at the final step, not from the jar's name. The jar is called Poker.jar, but the installer in the example is named netpoker because that is the value given to --name. Learners often expect the installer to inherit the jar's name, so it is worth checking this whenever you read a result.
Following Files from Classes to Jar
jpackage does not read your source code. It needs a jar file that already contains everything the program needs at run time: the compiled class files and any resource files, such as images. In the example, a network poker game draws on classes from two packages, netgame.common and netgame.fivecarddraw. It also loads an image file named cards.png that lives inside the netgame.fivecarddraw package.
The jar is built in two stages. First, the Java source files are compiled into class files, run from the directory that contains the top-level netgame folder. Then the jar command collects the class files and the image into one archive called Poker.jar. The jar command uses -c to create an archive and -f to name the file that will be created. The image must be listed alongside the class files.
- -c creates a new archive
- -f names the file that will be created, here
Poker.jar - The image path is listed with the class files, not left out
Why a Jar Alone Is Not Enough
A jar holds the program's compiled code and resources, so it contains everything the program needs except the runtime that executes it. Running the jar still requires Java on the target machine. An installer closes that gap. jpackage bundles a Java virtual machine together with the program, so the person who receives the installer does not need to prepare a Java environment before running the software.
The two constraints that shape every jpackage run also matter here. The resulting files are very large, because they include substantial parts of a Java execution environment. That is why the source describes jpackage as best suited to large, serious applications rather than small utilities. Use it when the benefit of bundling Java for your users outweighs the cost of distributing a big file.
Reading the jpackage Command
The example command uses four options. Each one answers a different question that jpackage needs answered before it can build anything. A useful way to read the command is to match each option to its question: Where is the jar? Which jar is the program? Which class starts the program? What should the result be called? Once you can answer those four questions for a new program, you can construct a jpackage command for it.
- --input locates the folder that holds the jar
- --main-jar names the jar file itself
- --main-class names the class containing the main program
- --name names the installer and the executable it installs
Each option answers one question. --input is where jpackage looks for the jar. --main-jar names the jar within that folder. --main-class names the class with the main program, which tells the installer where the program starts. --name controls what the installer and the program it installs are called. Because the options point at each other, a mismatch between them is a common source of trouble.
Tracing a Name Through the Pipeline
Following the name Poker through each stage
A developer builds Poker.jar from the poker game and runs jpackage with --name netpoker. What name does each artifact carry, and which option sets it?
- 1Jar stage
The jar command creates
Poker.jar. The name Poker comes from the -f argument, which names the archive. - 2jpackage input
--main-jar
Poker.jartells jpackage which jar to package. The jar's name is read here but does not decide the installer name. - 3Installer stage
--name netpoker sets the name of the installer and the executable it installs, so the installer is named netpoker.
- 4Result check
When you read a result, the installer name should match the --name value, not the jar name. A mismatch means you are looking at the wrong option.
The jar is Poker.jar, while the installer and the executable it installs are named netpoker, set by --name.
Platform Limits and Build Environment
jpackage can only make an installer for the type of computer and operating system you are currently using. You cannot run jpackage on Linux and expect a Windows installer. The platform differences come mainly from each operating system's packaging conventions and from the extra software the tool needs.
On MacOS, the author defined an alias that points directly to the jpackage program inside the JDK's installation folder. The source notes that newer versions of MacOS might set jpackage up properly, so the alias may not be needed. On Windows, the source says the tool should work and needs the WiX toolset. The author did not test the Windows path, so treat that claim as unverified.
Where a jpackage Run Fails
When a packaging attempt goes wrong, the first question is which stage failed. Each problem belongs to one stage: an incomplete jar, a jpackage run that did not start, or an installer built for the wrong system. Identifying the stage narrows down the fix. The most hidden failure is the one that happens inside the jar stage, because the installer can build without complaint even when the jar is missing an image the program needs.
Common mistake Assuming the installer takes the jar's name
What it looks likePoker.jar is built, and the developer expects an installer called Poker.
Why it failsThe installer's name comes from --name, not from the jar.
Do this insteadSet --name explicitly, and read the installer name against that value.
Common mistake Leaving the image out of the jar
What it looks likeThe jar contains the class files but not cards.png.
Why it failsThe program installs cleanly but fails when it reaches the code that draws a card.
Do this insteadList the resource file alongside the class files when running jar -cf.
Common mistake Expecting a Windows installer from a Linux machine
Why it failsjpackage builds only for the operating system it runs on.
Do this insteadRun jpackage on the target operating system, or on a machine that matches it.
Common mistake Treating a jar as a complete distribution
Checking Your Understanding
A developer packages a finished program into Poker.jar and runs jpackage with --name netpoker. A friend reports that the installer runs, but the game crashes when it tries to show a card. Using only the stages in this article, state which stage most likely failed, and explain how you would confirm it.
Hints
- Ask which stage the image belongs to: the jar stage or the installer stage.
- Think about whether the installer can detect a missing resource before the program runs.
- Check whether
cards.pngwas listed alongside the class files when the jar was built.
Key Takeaways
- A jar holds the compiled classes and resource files, but running it still requires Java on the target machine, so a jar alone may not be enough to hand to another person.
- jpackage bundles a Java virtual machine into an installer, and it builds from a jar rather than from source code, so the chain runs from class and resource files to a jar to an installer.
- The four main options answer four questions: --input locates the jar's folder, --main-jar names the jar, --main-class names the entry-point class, and --name names the installer and its executable.
- The most hidden failure occurs in the jar stage, such as a missing resource file, because the installer can build cleanly and the problem appears only at run time.
- jpackage builds only for the operating system it runs on, and the resulting installers are large, so it suits large, serious applications.