Concepts / Jar Files and Packaging Programs

Jar Files and Packaging Programs

A resource is data a program uses that is not code, such as images, sounds, and text; the user normally does not need to know where it is stored.

  • Programming

Why Programs Carry More Than Code

Most beginning Java programs consist only of code, so it is natural to think of a program as a collection of classes and nothing else. Real programs often carry other material along with their code: a picture shown on screen, a sound played during a game, or a block of text read at startup. Java calls this kind of material a resource.

The learner using the program normally sees the picture or hears the sound without ever thinking about the file that holds it. That gap between what the user sees and where the data actually lives is the reason resources need a dedicated lookup mechanism. This article follows one running example, the image file cards.png used by a card program, and asks one question throughout: when the program asks for cards.png, what has to be true about where that file is stored for the request to succeed?

What Counts as a Resource

Definition

A resource is data a program uses that is not code, such as images, sounds, and text. The user normally does not need to know where it is stored.

  • Image files, such as cards.png, shown on screen
  • Sound files played during a game
  • Text files, such as a block of text read at startup
Key point

The defining feature of a resource is that it is data rather than code. The program's classes tell it what to do; the resource supplies material the program uses while doing it.

Tracing the Two-Line Lookup

The first thing a program does with a resource is ask for it. The pattern below requests cards.png. Before reading the explanation, predict what the program needs in order to finish the request. Do not worry about the full meaning of each piece yet.

java
Notes on the code
  • Line 1 obtains a ClassLoader through the current object's class
  • Line 2 hands the file name to that ClassLoader and stores the result in a URL variable

Notice that the code never states a folder path or a drive letter. The lookup supplies only the file name. Whatever makes the file findable has to come from the object that performs the search. That object is introduced in the next section.

Programrunning card codeClassLoadersearch objectClass pathordered locationsURLlocation of cards.png1. getClassLoader()2. getResource("cards.png")3. match found4. URL returned
In what order do the two lines pass control and data, from the program's request for cards.png to the URL being returned?

Read the diagram as a single request. The program never opens a folder itself. It sends the file name to the ClassLoader, which performs the search, and it receives a URL in return. This delegation is why the user of the program can remain unaware of where the file lives.

The ClassLoader as a Search Object

The object that does the searching is a class loader. In Java it is represented by an object of type ClassLoader. Its everyday job is to find and load class files, and it can also find resource files that sit in the same kinds of places. Because one object handles both jobs, a resource request does not need its own separate search system.

Key point

The purpose of a ClassLoader can be summed up in one question: where should I look? Everything it can find, it finds by checking a fixed set of locations that it was given.

The ClassLoader's list of places to check is called the class path. The class path is the list of locations searched, which generally includes the standard classes location and the current directory, plus the jar file if the program is packaged in one. A resource is located by obtaining a ClassLoader and calling getResource with the file name, and that call returns a URL the program can use.

Class Path Order and Jar Position

The class path is an ordered list, and the position of each entry matters. The ClassLoader works through the entries in sequence rather than searching all of them at once. The standard classes location and the current directory are the ordinary entries, and a jar file is added to the list when the program is packaged in one.

Standard classeslocationsearched firstCurrent directorysearched secondJar filepresent when packaged
Which class path entry is searched first, second, and so on, and where does a jar file fit in that list?

The index map shows the default entries in the order described in the source. The source does not give a fixed rule for exactly where the jar file sits in that list, so the diagram shows only that it is one of the entries a packaged program adds. What the source does establish is that the ClassLoader searches the class path's locations, and a file is found only if one of those locations holds it.

Inside a Jar File

When a program is packaged in a jar file, the jar serves as one of the locations on the class path. The source describes packaging as the case where the jar file is part of the class path, which means the ClassLoader can look inside it for both class files and resource files. The program's code and its resources can therefore travel together as one unit while the lookup still works the same way for the code and the data.

Key point

A jar file is a packaged container that is searched like any other class path location. Its presence on the class path is what lets a program carry its resources with it.

Following the ClassLoader Search

Now follow one search for cards.png from start to finish. The ClassLoader takes the file name and checks the first class path location. If the file is there, the search stops and the URL is returned. If the file is not there, the ClassLoader moves on to the next location. The search continues entry by entry until the file is found or the list is exhausted.

Receive cards.pngfile name from getResourceCheck next entrystart with first entryFile present?in this locationMore entries?any locations leftReturn URLsearch stopsNo URLsearch exhaustedyesnoyesno
When the ClassLoader looks for cards.png, what does it check first, what happens on a hit or a miss, and when does it stop?

The search has two possible stopping points. It stops with success the moment a location holds cards.png, and it stops with failure only after every location has been checked without a match. The flowchart is the same logic as the sequence diagram above, now shown at the level of individual location checks.

Where a Resource Lookup Fails

Because the lookup depends entirely on the class path, most failures come from a mismatch between where the file is stored and where the ClassLoader searches. The source notes that these failures are the most common cause of a resource that seems to be missing, and each of the following is worth checking.

  • Common mistake

    Storing cards.png in a folder that is not on any searched location

    What it looks like

    The file sits in a sibling folder that the class path never lists.

    Why it fails

    The ClassLoader can only find a file in a location it was given. A file outside every searched location is invisible to the lookup.

    Do this instead

    Place the file in a location the class path searches, such as the current directory or inside the packaged jar.

  • Common mistake

    Expecting the program to find a file by a folder path it was never given

    What it looks like

    Writing a full drive path into the getResource call instead of the file name.

    Why it fails

    The lookup supplies only the file name, and the ClassLoader decides where to look from its class path.

    Do this instead

    Pass only the file name, and make sure the file is stored on a searched location.

  • Common mistake

    Assuming a missing resource means the code is broken, when the file is simply absent from every location checked

What do you think happens?

If cards.png is missing from every class path entry, what does the program receive from getResource?

Reveal answer
Answer:

No URL. In Java, getResource returns null when the file cannot be found.

The search checks every location and finds no match, so there is no URL to return. The program receives nothing usable in place of the expected URL, which is the failure point the flowchart ends on.

Practice Tracing a Lookup

MEDIUM

A card program calls getResource for "cards.png", but the file is stored in a folder that is not on the class path. Trace the search: which locations does the ClassLoader check, at what point does it stop, and what does the program receive?

Hints
  • Start from the sequence diagram: the request goes to the ClassLoader first.
  • Use the flowchart: each location is checked in turn until the list runs out.
  • Think about whether the folder with the file is one of the entries listed on the class path.

Key Takeaways

  • A resource is data a program uses that is not code, such as images, sounds, and text, and the user normally does not need to know where it is stored.
  • A program requests a resource by obtaining a ClassLoader and calling getResource with only the file name, which returns a URL the program can use.
  • The ClassLoader finds files by searching the class path, an ordered list of locations that generally includes the standard classes location and the current directory, plus the jar file when the program is packaged.
  • A lookup fails when the file is not on any searched location, so the program receives no URL and the search must be traced back to where the file is stored.