Concepts / Packages and Class Organization in Java

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.

  • Programming

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?

  • Poker, inherited from the jar

  • netpoker, from the --name option

  • Poker.jar, the same as the jar

Reveal answer
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.

Notes on the code
  • -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
Compiled classfilesfrom the netgame sourcefoldersPoker.jarbuilt by the jar commandjpackagewith --input, --main-jar,--main-class, --namenetpoker installerbundles a Java virtualmachineResource filescards.pngcollected by jar -cflisted with classesread as inputproduces
What happens to the compiled .class files and resource files, in what order, to end up as a distributable installer? Each arrow is a step where one kind of file becomes another, and each step is a possible place for failure.

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.

Class and resourcefilesthe program itselfProgram and itsclassesplaced on the machineJava runtime neededmust already be on themachineBundled Java virtualmachineno separate Java setup
How does the jar differ from the installer in what it contains, what it requires on the target machine, and who can run it? The jar needs Java already present; the installer carries its own Java support.

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.

Notes on the code
  • --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
jpackagethe packaging tool--inputfolder that holds the jar--main-jarthe jar file, such asPoker.jar--main-classthe class with the mainprogram--namenames the installer andexecutable
Which part of the command points to the folder, the jar, the entry-point class, and the application name, and how does each one connect to the others? The jar's folder, the jar, and the main class all describe the same program; the name only labels the output.

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

Worked example

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?

  1. 1
    Jar stage

    The jar command creates Poker.jar. The name Poker comes from the -f argument, which names the archive.

  2. 2
    jpackage input

    --main-jar Poker.jar tells jpackage which jar to package. The jar's name is read here but does not decide the installer name.

  3. 3
    Installer stage

    --name netpoker sets the name of the installer and the executable it installs, so the installer is named netpoker.

  4. 4
    Result 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.

Result

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 like

    Poker.jar is built, and the developer expects an installer called Poker.

    Why it fails

    The installer's name comes from --name, not from the jar.

    Do this instead

    Set --name explicitly, and read the installer name against that value.

  • Common mistake

    Leaving the image out of the jar

    What it looks like

    The jar contains the class files but not cards.png.

    Why it fails

    The program installs cleanly but fails when it reaches the code that draws a card.

    Do this instead

    List the resource file alongside the class files when running jar -cf.

  • Common mistake

    Expecting a Windows installer from a Linux machine

    Why it fails

    jpackage builds only for the operating system it runs on.

    Do this instead

    Run 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

MEDIUM

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.png was 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.