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.
Prerequisites
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
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
Navigate to the
srcdirectory.From
src, compileHello.javaDon’t use the-doption forjavacin this step.Write on exit ticket: What happened when we executed the previous command? Be as detailed as possible.
From
src, execute the program.Navigate to the
cs1302-hellodirectory.Execute the
treecommand from inside ofcs1302-hellodirectory. 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-hellodirectory by providing the relative path (using tab completion) to the file from thecs1302-hellodirectory. This means you would rarely use the cd command while working on an assignment. When Unix beginners overuse thecdcommand, they often find themselves lost in the directory structure which can lead to mistakes and, in rare cases, frustration!Write on exit ticket: From
cs1302-hello, what is the command to delete the compiled (.class) file fromsrc.For better organization, let’s separate the source code from the compiled code. Directly inside the
cs1302-hellodirectory, add a subdirectory calledbin.From within
cs1302-hello, execute a single command to compileHello.javaand place the compiled code into thebindirectory? When typing the command, remember to use tab completion!Tricky: In your groups: try to execute the
Helloprogram fromcs1302-hello. Write the command you used in your notes.Execute the
treecommand from directly within yourcs1302-hellodirectory. 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
Write on exit ticket: From your home directory (not
cs1302-hello), what is the single command to run theHelloprogram?Solution
java -cp cs1302-hello/bin Hello
Write on exit ticket: From your home directory, what is the command to delete the
Hello.classfile from thebinfolder?Solution
rm cs1302-hello/bin/Hello.class
Navigate to
cs1302-helloExecute the
treecommand. You should see output similar to the following:. |--- bin |--- src | |--- Hello.java
Setup for Part 3: Using the appropriate Unix commands, adjust the files/subdirectories within
cs1302-helloto 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
.javafiles into the appropriate package directory (done in previous section)Include an appropriate package statement at the top of each
.javafile (do this now).
Compiling Hello.java to a Named Package
Move the
Hello.javafile (source code) into thecs1302.examplepackage.Compile
Hello.javaspecifyingbinas the destination for compiled code. Write the command used in your notes.Solution
javac -d bin src/cs1302/example/Hello.java
Execute the
treecommand from directly within yourcs1302-hellodirectory. 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
Now, run the
Helloprogram. Write the command you used in your notes.Solution
java -cp bin cs1302.example.Hello
From your home directory (not
cs1302-hello), what is the single command to run theHelloprogram? 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:
M-v
C-p
M-b C-b + C-f M-f
C-n
C-v
C-x C-f
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
Navigate to the
cs1302-hellofolder if you aren’t there already.Add a
cs1302.utilitypackage directory to your hierarchy. Hint: Theutilitydirectory will need to be inside of thecs1302folder.Create a class called
MyMethodsin thecs1302.utilitypackage. The file will need to be namedMyMethods.java.Double check that you typed the class declaration. This class won’t need a
mainmethod because it won’t be run directly.Add a single, static method called
maxto theMyMethodsclass 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
Implement the body of the
maxmethod. The method should determine and return the bigger of twointvalues 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 theScannerclass inside of theMyMethodsclass.Run the
treecommand. You should see output similar to the following:. └── src └── cs1302 ├── example │ └── Hello.java └── utility └── MyMethods.java
Compiling the Code
From
cs1302-hello, compileMyMethods.javaand place the byte code in thebindirectory? Remember, there are no dependencies when compilingMyMethods.java.Solution
javac -d bin src/cs1302/utility/MyMethods.java
Now that you’ve compiled both
Hello.javaandMyMethods.java, executetreeand look in thebindirectory. Notice the directory hierarchy that was automatically created!
Calling max
Modify the
Helloclass in theHello.javafile to print out the maximum of two values input by the user.Hint
To accomplish this, in the
mainmethod of yourHelloclass, you should read two integers from a validScannerobject and pass those values into themaxmethod you created in theMyMethodsutility class. In other words, you should call themaxmethod inMyMethodsfrom themainmethod in yourHelloclass and print the result.You must import
MyMethodsinHello.java. Why?Solution
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
Write on exit ticket: What is the command to compile the
Helloclass from thecs1302-hellodirectory and place the compiled code intobin?Hint
There is now a dependency in
Hello.java. It relies on the code fromMyMethods, so the compiler needs to know where to find that class.Solution
javac -d bin -cp bin src/cs1302/example/Hello.java
Execute the
treecommand from directly within yourcs1302-hellodirectory. 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
Write on exit ticket: What is the command to run
Hello?Solution
java -cp bin cs1302.example.Hello
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.
student // you are here
|--- cs1302-packages
| |--- src
| |--- cs1302
| |--- hello
| |--- HelloWorld.java
Without changing directories, what exact command would you type to compile
HelloWorld.javatobinassuming it is in thecs1302.hellopackage and the appropriate package statement is included in the code?Solution
javac -d cs1302-packages/bin cs1302-packages/src/cs1302/hello/HelloWorld.java
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-packagesas well asbinto provide a valid relative path.