3. Packages Lesson

Java Packages

Java Packages

Lesson Objectives

This lesson is designed to provide further practice with command-line text editors as well as compiling Java code organized into packages on a Unix system.

Course-Specific Learning Outcomes

  • LO1.a: Navigate and modify files, directories, and permissions in a multi-user Unix-like environment.

  • LO1.c: Create and modify text files and source code using a powerful terminal-based text editor such as Emacs or Vi.

  • LO1.d: (Partial) Use shell commands to compile new and existing software solutions that are organized into multi-level packages and have external dependencies.

Note

Solutions to the coding parts of this lesson are provided if you toggle “Show Solutions” above. Students are encouraged to review the text/videos in the Packages Chapter for instructions on how to properly create packages directories and details on compilation commands.

Part 1: Compiling to Default Package
Download Starter Code
  1. Use the following command to download the starter code for this chapter and places it into a subdirectory called cs1302-hello:

    sh -c "$(curl -fsSl https://cs1302uga.github.io/cs1302-book/_bundle/cs1302-hello.sh)"
    
    - downloading cs1302-hello bundle...
    - verifying integrity of downloaded files using sha256sum...
    - extracting downloaded archive...
    - removing intermediate files...
    subdirectory cs1302-hello successfully created
    
Compile Hello.java to Default Package
  1. Navigate to the src directory.

  2. From src, compile Hello.java Don’t use the -d option for javac in this step.

  3. Write on exit ticket: What happened when we executed the previous command? Be as detailed as possible.

  4. From src, execute the program.

  5. Navigate to the cs1302-hello directory.

  6. Execute the tree command from inside of cs1302-hello directory. You should see output similar to this:

    .
    |--- src
    |      |--- Hello.class
    |      |--- Hello.java
    
    Pro Tip

    Unless it is specifically stated, it is best to always work from the main project directory. For example, while working on the source code for this exercise, you can modify all of the files without leaving the cs1302-hello directory by providing the relative path (using tab completion) to the file from the cs1302-hello directory. This means you would rarely use the cd command while working on an assignment. When Unix beginners overuse the cd command, they often find themselves lost in the directory structure which can lead to mistakes and, in rare cases, frustration!

  7. Write on exit ticket: From cs1302-hello, what is the command to delete the compiled (.class) file from src.

  8. For better organization, let’s separate the source code from the compiled code. Directly inside the cs1302-hello directory, add a subdirectory called bin.

  9. From within cs1302-hello, execute a single command to compile Hello.java and place the compiled code into the bin directory? When typing the command, remember to use tab completion!

  10. Tricky: In your groups: try to execute the Hello program from cs1302-hello. Write the command you used in your notes.

  11. Execute the tree command from directly within your cs1302-hello directory. If the previous steps were executed correctly, you should see the following output:

    .
    |--- bin
    |      |--- Hello.class
    |--- src
    |      |--- Hello.java
    

    Note: If you see any tilda (~) files, those are just backup copies of older versions of your files. You can ignore those.

Part 2: Test Yourself
  1. Write on exit ticket: From your home directory (not cs1302-hello), what is the single command to run the Hello program?

    Solution

    java -cp cs1302-hello/bin Hello

  2. Write on exit ticket: From your home directory, what is the command to delete the Hello.class file from the bin folder?

    Solution

    rm cs1302-hello/bin/Hello.class

  3. Navigate to cs1302-hello

  4. Execute the tree command. You should see output similar to the following:

    .
    |--- bin
    |--- src
    |      |--- Hello.java
    
  5. Setup for Part 3: Using the appropriate Unix commands, adjust the files/subdirectories within cs1302-hello to look like the following:

    .
    |--- bin
    |--- src
    |    |--- cs1302
    |         |--- example
    |              |--- Hello.java
    
Part 3: Compiling to Named Package
Introduction

In large projects, code is organized into named packages similar to how you might organize your personal photos into subfolders.

To move code into a named package, there are two steps:

  • Place the .java files into the appropriate package directory (done in previous section)

  • Include an appropriate package statement at the top of each .java file (do this now).

Compiling Hello.java to a Named Package
  1. Move the Hello.java file (source code) into the cs1302.example package.

  2. Compile Hello.java specifying bin as the destination for compiled code. Write the command used in your notes.

    Solution

    javac -d bin src/cs1302/example/Hello.java

  3. Execute the tree command from directly within your cs1302-hello directory. If the previous steps were executed correctly, you should see the following output:

    Note: If you see any tilda (~) files, those are just backup copies of older versions of your files. You can ignore those.

    .
    |--- bin
    |      |--- cs1302
    |           |--- example
    |                |--- Hello.class
    |--- src
    |      |--- cs1302
    |           |--- example
    |                |--- Hello.java
    
  4. Now, run the Hello program. Write the command you used in your notes.

    Solution

    java -cp bin cs1302.example.Hello

  5. From your home directory (not cs1302-hello), what is the single command to run the Hello program? Write the command you used in your notes.

    Solution

    java -cp cs1302-hello/bin cs1302.example.Hello

Emacs Aside

In the next section, you will be writing code using Emacs in class for the first time. While working through that section, try to incorporate the following commands:

Listing 8 Navigation
          M-v
          C-p
  M-b C-b  +  C-f M-f
          C-n
          C-v
Listing 9 Open File in Current Buffer
C-x C-f
Listing 10 Minimize / Bring to Foreground
C-z (run within Emacs)
fg (run from terminal)
Part 4: Code Dependencies

Note

This section requires completion of the first three parts. If you missed class, please find a classmate who has those parts completed.

Adding a Dependency
  1. Navigate to the cs1302-hello folder if you aren’t there already.

  2. Add a cs1302.utility package directory to your hierarchy. Hint: The utility directory will need to be inside of the cs1302 folder.

  3. Create a class called MyMethods in the cs1302.utility package. The file will need to be named MyMethods.java.

  4. Double check that you typed the class declaration. This class won’t need a main method because it won’t be run directly.

  5. Add a single, static method called max to the MyMethods class with the following signature:

    /**
     * Returns the larger of the two input parameters. If the parameters
     * are equal, either value can be returned.
     *
     * @param num1 the first number to check.
     * @param num2 the second number to check.
     * @return the larger of the two parameters.
     */
    public static int max(int num1, int num2) {
        // Your code here
    } // max
    
  6. Implement the body of the max method. The method should determine and return the bigger of two int values supplied as parameters to the method. These values will be supplied when you call the method in a later step. Note: You should not use the Scanner class inside of the MyMethods class.

  7. Run the tree command. You should see output similar to the following:

    .
    └── src
        └── cs1302
            ├── example
            │   └── Hello.java
            └── utility
                └── MyMethods.java
    
Compiling the Code
  1. From cs1302-hello, compile MyMethods.java and place the byte code in the bin directory? Remember, there are no dependencies when compiling MyMethods.java.

    Solution

    javac -d bin src/cs1302/utility/MyMethods.java

  2. Now that you’ve compiled both Hello.java and MyMethods.java, execute tree and look in the bin directory. Notice the directory hierarchy that was automatically created!

Calling max
  1. Modify the Hello class in the Hello.java file to print out the maximum of two values input by the user.

    Hint

    To accomplish this, in the main method of your Hello class, you should read two integers from a valid Scanner object and pass those values into the max method you created in the MyMethods utility class. In other words, you should call the max method in MyMethods from the main method in your Hello class and print the result.

    You must import MyMethods in Hello.java. Why?

    Solution
    Listing 11 In Hello.java
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
    
        System.out.print("Enter a number: ");
        int num1 = input.nextInt();
        System.out.print("Enter another number: ");
        int num2 = input.nextInt();
    
        // Use our new max method to find out which is bigger.
        int bigger = MyMethods.max(num1, num2);
        System.out.println(bigger + " is bigger");
    
    } // main
    
  2. Write on exit ticket: What is the command to compile the Hello class from the cs1302-hello directory and place the compiled code into bin?

    Hint

    There is now a dependency in Hello.java. It relies on the code from MyMethods, so the compiler needs to know where to find that class.

    Solution

    javac -d bin -cp bin src/cs1302/example/Hello.java

  3. Execute the tree command from directly within your cs1302-hello directory. If the previous steps were executed correctly, you should see the following output:

    Note: If you see any tilde (~) files, those are just backup copies of older versions of your files. You can ignore those.

    .
    |--- bin
    |      |--- cs1302
    |           |--- example
    |                |--- Hello.class
    |           |--- utility
    |                |--- MyMethods.class
    |--- src
    |      |--- cs1302
    |           |--- example
    |                |--- Hello.java
    |           |--- utility
    |                |--- MyMethods.java
    
  4. Write on exit ticket: What is the command to run Hello?

    Solution

    java -cp bin cs1302.example.Hello

  5. Run your code to make sure everything is working properly. Demonstrate to your instructor if they are available.

Additional Practice: Named Packages

Additional Practice: Named Packages

Note

Activity objective: learn how to organize code using packages, compile Java programs with proper directory and classpath configurations, and execute them using FQNs e.g. what happens when they omit the package statement, how the commands change relative to location, understanding FQNs and how they relate to file paths and package structure, and sequences of compiling and executing a Java program that uses named packages.

Question: Running a Program

You are working with a file with the relative path:

src/pkg/example/myapp/Welcome.java

which includes the first line:

package pkg.example.myapp;

What is the FQN of the class? After compiling it to the bin/ directory, what command would you use to run it from inside the project/ folder?

Solution

FQN: pkg.example.myapp.Welcome

Command:

java -cp bin pkg.example.myapp.Welcome

Explanation:

The fully qualified name (FQN) includes the package and class name. When running from the project/ folder, the classpath must point to the bin/ directory where the class was compiled.

Question: Compiling and Running

Consider the following file structure. Assume you are in the student directory.

Listing 12 You are in the student directory.
student     // you are here
|--- cs1302-packages
|           |--- src
|                |--- cs1302
|                     |--- hello
|                          |--- HelloWorld.java
  1. Without changing directories, what exact command would you type to compile HelloWorld.java to bin assuming it is in the cs1302.hello package and the appropriate package statement is included in the code?

    Solution
    javac -d cs1302-packages/bin cs1302-packages/src/cs1302/hello/HelloWorld.java
    
  2. Without changing directories, How would you run HelloWorld?

    Solution
    java -cp cs1302-packages/bin cs1302.hello.HelloWorld
    

    Explanation: As the file is now compiled, FQN must match the package+class name and the classpath must include cs1302-packages as well as bin to provide a valid relative path.