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.java
program:javac -d bin src/HelloWorld.java
Explain why this command will not work if executed from the
example
directory.Solution
This command will not compile the code because the system will not be able to find
HelloWorld.java
given the invalid relative pathsrc/HelloWorld.java
. Thesrc
directory is not directly withinexample
, so it will not be found.Additionally, the relative path to
bin
is 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
bin
folder is:javac -d cs1302-packages/bin cs1302-packages/src/HelloWorld.java
Once the code is compiled, how could we run
HelloWorld
without changing directories?Solution
java -cp cs1302-packages/bin HelloWorld
Why do we use
-cp bin
instead of-cp src
when running the program withjava
?Solution
The
src/
directory contains your source code (.java
files), not compiled bytecode.The
bin/
directory contains the compiled ``.class`` files generated byjavac
.When running a Java program, the JVM looks for
.class
files in the classpath you provide.Therefore, you specify
-cp bin
so Java can find theHelloWorld.class
file 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.class
file to the current directory (bin
in this case).Explain why the command fails.
Solution
Since we are inside the
bin
folder, the relative path toHelloWorld.java
is incorrect. We are tellingjavac
to look for the filesrc/HelloWorld.java
relative 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
HelloWorld
frombin/
?Solution
Two possible solutions (of many):
java HelloWorld
java -cp . HelloWorld
What command would run
HelloWorld
from 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.java
is placed injava-tutorial
since that is the directory we ran theemacs
command 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/
.. dropdown:: Solution
:chevron: down-up
:icon: light-bulb
The correct command is:
.. code-block:: shell
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.java
Solution
Use the Java compiler to compile the
Calculator.java
file located insrc/com/tools/math/
. Look for any required compiled classes in thebin
directory (-cp bin
), and store the resulting.class
file in the correct package directory structure insidebin/
(-d bin
).Show how the directory structure looks now after compiling
Calculator.java
with the command:javac -cp bin -d bin src/com/tools/math/Calculator.java
Solution
Resulting directory structure:
project ├── bin │ └── com │ └── tools │ └── math │ └── Calculator.class └── src └── com └── tools └── math └── Calculator.java
The
src
folder has the original source file, and the compiled.class
file is placed inbin
following 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
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
.class
files are stored in subdirectories underbin
matching their package names.Solution
The
.class
files are stored in subdirectories underbin
that 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
.class
files.If the directory structure inside
bin
does 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
NoClassDefFoundError
orClassNotFoundException
.