2.6. Additional Practice Exercises¶
Question 1
Consider the directory structure below and assume your present working
directory is example.
example // You are here
└── cs1302-packages
├── bin
└── src
└── HelloWorld.java
Without changing directories, you execute the following command to compile the
HelloWorld.javaprogram:javac -d bin src/HelloWorld.java
Explain why this command will not work if executed from the
exampledirectory.Solution
This command will not compile the code because the system will not be able to find
HelloWorld.javagiven the invalid relative pathsrc/HelloWorld.java. Thesrcdirectory is not directly withinexample, so it will not be found.Additionally, the relative path to
binis incorrect in this context.How could we modify the command, without changing directories, to get it to successfully compile
HelloWorld.java?Solution
The correct way to write the command and compile the code to the proper
binfolder is:javac -d cs1302-packages/bin cs1302-packages/src/HelloWorld.java
Once the code is compiled, how could we run
HelloWorldwithout changing directories?Solution
java -cp cs1302-packages/bin HelloWorldWhy do we use
-cp bininstead of-cp srcwhen running the program withjava?Solution
The
src/directory contains your source code (.javafiles), not compiled bytecode.The
bin/directory contains the compiled ``.class`` files generated byjavac.When running a Java program, the JVM looks for
.classfiles in the classpath you provide.Therefore, you specify
-cp binso Java can find theHelloWorld.classfile and execute it.
Question 2
Note
In this question, we change directories to compile to better understand how the commands work. In general, you will stay in the main project directory when compiling.
Suppose you created the following directory structure within your home directory:
cs1302-packages/
├── bin/
└── src/
└── HelloWorld.java
And now you run the following commands:
cd ~/cs1302-packages/bin
javac -d . src/HelloWorld.java
What does
-d .mean?Solution
.is an alias for the current directory in Unix. So, we are setting the destination for the.classfile to the current directory (binin this case).Explain why the command fails.
Solution
Since we are inside the
binfolder, the relative path toHelloWorld.javais incorrect. We are tellingjavacto look for the filesrc/HelloWorld.javarelative to this directory, which does not exist.What would be the correct compile command from within
bin?Solution
javac -d . ../src/HelloWorld.java
What would be the command to run
HelloWorldfrombin/?Solution
Two possible solutions (of many):
java HelloWorldjava -cp . HelloWorld
What command would run
HelloWorldfrom your home directory (~)?Solution
java -cp cs1302-packages/bin HelloWorld
Question 3
Note
In this question, we use directories code and compiled
instead of src and bin to show that the names can
change. Generally, you will see src and bin because that
has become the convention.
Imagine that you log into Odin and execute the following commands in the order in which they are presented:
cd ~
mkdir java-tutorial
cd java-tutorial
mkdir code
mkdir compiled
emacs Welcome.java
Now, inside Emacs, you write:
1/**
2* A simple program that prints "Welcome!" to the console.
3*/
4public class Welcome {
5
6 /**
7 * The main entry point of the program.
8 *
9 * @param args command-line arguments (not used)
10 */
11 public static void main(String[] args) {
12 System.out.println("Welcome!");
13 } // main
14} // Welcome
After saving and exiting Emacs, which folder contains
Welcome.java?Solution
The file
Welcome.javais placed injava-tutorialsince that is the directory we ran theemacscommand from.The directory structure would look as follows:
java-tutorial // You are here ├── code ├── compiled └── Welcome.java
Without changing directories, what happens if you run the following commands?
mv Welcome.java code javac -d compiled code/Welcome.java java -cp compiled Welcome
Solution
The commands correctly compile and run the code!
After compilation, the directory structure should be as follows:
java-tutorial ├── code │ └── Welcome.java └── compiled └── Welcome.class
Question 4
You want to compile a file located at
~/java-labs/lab1/src/Greetings.java and place the .class file
in ~/java-labs/lab1/classes. What exact command would you use from
the home directory?
Folder structure for reference:
// You are in the parent folder - your home directory
java-labs/
└── lab1/
├── src/
│ └── Greetings.java
└── classes/
Solution
The correct command is:
javac -d java-labs/lab1/classes java-labs/lab1/src/Greetings.java
Question 5
Keeping the textbook example from section 2.3, suppose you do not
include a package statement at the top of your .java file (i.e.,
you forgot to add package cs1302.hello; at the top).
If your .java file is located at
src/cs1302/hello/HelloWorld.java and you compile it using:
javac -d bin src/cs1302/hello/HelloWorld.java
Where does the resulting .class file go?
Solution
The compiled HelloWorld.class file will be placed directly into
bin/HelloWorld.class. No package directories will be created
inside bin because the .java file does not declare a
package.
Question 6
Important
From here on, the activities are based on section 2.4 Code Dependencies.
Explain the following command in English:
javac -cp bin -d bin src/com/tools/math/Calculator.javaSolution
Use the Java compiler to compile the
Calculator.javafile located insrc/com/tools/math/. Look for any required compiled classes in thebindirectory (-cp bin), and store the resulting.classfile in the correct package directory structure insidebin/(-d bin).Show how the directory structure looks now after compiling
Calculator.javawith the command:javac -cp bin -d bin src/com/tools/math/Calculator.javaSolution
Resulting directory structure:
project ├── bin │ └── com │ └── tools │ └── math │ └── Calculator.class └── src └── com └── tools └── math └── Calculator.javaThe
srcfolder has the original source file, and the compiled.classfile is placed inbinfollowing the package hierarchy.
Question 7
Given two new classes:
cs1302.util.Helper(no dependencies)cs1302.hello.Greeter(depends on Helper)
Write the sequence of compilation commands to correctly compile both classes, assuming all source files are present.
Solution
Compilation sequence:
To compile Helper (no dependencies):
javac -d bin src/cs1302/util/Helper.java
Then compile Greeter (depends on Helper), telling the compiler
where to find Helper.class:
javac -cp bin -d bin src/cs1302/hello/Greeter.java
Dependency diagram:
src/
├── cs1302/
│ ├── util/
│ │ └── Helper.java
│ └── hello/
│ └── Greeter.java ---> depends on Helper
bin/
├── cs1302/
│ ├── util/
│ │ └── Helper.class
│ └── hello/
│ └── Greeter.class
Question 8
Given the directory tree below after compilation:
cs1302-packages/
├── bin/
│ └── cs1302/
│ ├── hello/
│ │ └── HelloWorld.class
│ └── util/
│ └── HelloUtility.class
└── src/
└── cs1302/
├── hello/
│ └── HelloWorld.java
└── util/
└── HelloUtility.java
Explain why the
.classfiles are stored in subdirectories underbinmatching their package names.Solution
The
.classfiles are stored in subdirectories underbinthat match their package names because the JVM and compiler use this folder hierarchy to map package names to filesystem locations.How does this structure assist the Java runtime when executing your program?
Solution
This structure allows Java to locate and load classes by converting package names with dots (.) into folder paths, enabling the classloader to find the correct
.classfiles.If the directory structure inside
bindoes not match the package names, what issues might arise at runtime?Solution
If the directory structure does not match the package names, the JVM will not find the classes properly, resulting in runtime errors like
NoClassDefFoundErrororClassNotFoundException.