Concepts / Class Files and Compilation in Java

Class Files and Compilation in Java

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 Extra Files

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 may be shown on screen, a sound may be played during a game, and a block of text may be 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, which a card program uses. Keep one question in mind as you read: when the program asks for cards.png, what has to be true about where that file is stored for the request to succeed?

What do you think happens?

The program asks for cards.png using only the file name, with no folder path. What does the program need to finish the request?

Reveal answer
Answer:

It needs a ClassLoader, the object that performs the search and knows where to look for the file.

The code never states a folder path or drive letter. The lookup supplies only the file name, so whatever makes the file findable has to come from the object that performs the search.

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.

  • Images, such as a picture shown on screen (the cards.png file in this article's running example)
  • Sounds, such as a sound played during a game
  • Text, such as a block of text read at startup

The defining feature is the word not in the definition. A class file contains code the program runs, while a resource is material the program uses while running. Both live alongside the program, but a resource is only read and used, and it is found through the same search mechanism that finds class files.

Tracing the Two-Line Lookup

The first thing a program does with a resource is ask for it. The lookup for cards.png takes two lines. Before reading the explanation, look at the pattern below and predict what the program needs in order to finish the request. The sections that follow explain each part.

Code walkthrough
ClassLoader loader = getClass().getClassLoader();
URL url = loader.getResource("cards.png");
  1. 1
    Line 1 obtains a ClassLoader through the current object's class and stores it in a variable named loader.
  2. 2
    Line 2 passes the file name cards.png to that ClassLoader by calling getResource, and stores the returned URL in a variable named url.
  3. 3
    The program never opens a folder itself. It delegates the search to the ClassLoader and receives a URL in return.
  • getClass() gives the class of the current object
  • getClassLoader() returns the ClassLoader associated with that class
  • getResource("cards.png") hands only the file name to the ClassLoader
  • The result is stored in a variable of type URL

Notice what the code does not contain. There is no folder path and no drive letter. The file name is the only information the program gives. The lookup works because the ClassLoader already knows which locations to search, and that knowledge comes from the class path, which the next section describes.

Program codecurrent objectClassLoadersearches for filesClass path locationsplaces to search1. getClassLoader()2. getResource(cards.png)3. search locations4. cards.png found5. URL returned
In what order do the program's request, the ClassLoader, and the class path locations interact to find cards.png?

Read the diagram from top to bottom. The program first obtains the ClassLoader, then sends the file name. The ClassLoader checks the class path locations, and if the file is found there, the request returns a URL to the program. The program then uses that URL and never needs to know the folder where cards.png is stored.

The ClassLoader and the Class Path

A ClassLoader is an object that finds class files and resource files by searching the class path. 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 a single object handles both, a resource request does not need its own separate search system.

The ClassLoader answers one question: where should I look? Everything it can find, it finds by checking a fixed set of locations that it was given. Those locations are the class path.

The class path is the list of locations searched. It generally includes the standard classes location and the current directory. If the program is packaged in a jar file, the jar file is also on the class path. A resource is only findable if the file sits in one of these searched locations.

Where a Lookup Fails

The lookup depends entirely on the class path. Because of that, most failures come from a mismatch between where the file is stored and where the ClassLoader searches. The decision below shows the single point at which a request either succeeds or fails.

Request cards.pngfile name onlyIs cards.png on asearched location?checked against the classpathProgram receives aURLfile can be usedFile is not foundstored off the class pathsearchyesno
At which decision point does the search succeed or fail, and what happens to the program in each case?

On the yes branch the request succeeds, and the program receives the URL it asked for. On the no branch the file is not on any searched location, so the lookup does not locate it. The source does not describe the exact result the program receives on that branch, so check how your program handles a missing result when you write code that depends on a resource.

  • Common mistake

    Assuming the file is found because it sits in the same project folder as the code

    What it looks like

    cards.png is placed in a folder that is not among the class path locations

    Why it fails

    The ClassLoader only searches the locations it was given through the class path, so a file outside those locations is not searched.

    Do this instead

    Confirm that the file is in one of the searched locations, such as the standard classes location, the current directory, or the jar file if the program is packaged in one.

  • Common mistake

    Putting a folder path in the file name passed to getResource

    What it looks like

    getResource("images/cards.png") when the file sits directly in a searched location

    Why it fails

    The lookup supplies only the file name and relies on the class path for location, so a path that does not match a searched location will not succeed.

    Do this instead

    Pass the file name as the lookup expects and make sure the file sits in a location the class path covers.

  • Common mistake

    Forgetting that a packaged program changes the search locations

    What it looks like

    A program is moved into a jar file, but the resource is left in a folder outside the jar

    Why it fails

    The jar file is part of the class path when the program is packaged in one, so the resource needs to be in a location the packaged program actually searches.

    Do this instead

    Check where the resource ends up after packaging, and make sure the search locations used by the packaged program include it.

Practice: Trace a New Resource

EASY

A program needs a sound file named hit.wav during a game. Using the same two-line pattern as cards.png, write the two lines that request hit.wav. Then describe, step by step, what the ClassLoader does with the file name, and state the one condition under which the request succeeds.

Hints
  • Only the file name goes into getResource, just as with cards.png.
  • Think about the ClassLoader as the object that answers where should I look.
  • The success condition is about whether hit.wav sits in one of the searched locations 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 with two lines: it obtains a ClassLoader through the current object's class, then calls getResource with only the file name, receiving a URL in return.
  • The ClassLoader is the object that finds class files and resource files by searching the class path, which lists the locations searched, including the standard classes location and the current directory, plus the jar file if the program is packaged in one.
  • A resource lookup fails when the file is not on a searched location, because the search depends entirely on the class path and not on where the code happens to sit.