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
  1. Without changing directories, you execute the following command to compile the HelloWorld.java program:

    Listing 2.11 Executed from the example directory
    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 path src/HelloWorld.java. The src directory is not directly within example, so it will not be found.

    Additionally, the relative path to bin is incorrect in this context.

  2. 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:

    Listing 2.12 Works when executed from the example directory
    javac -d cs1302-packages/bin cs1302-packages/src/HelloWorld.java
    
  3. Once the code is compiled, how could we run HelloWorld without changing directories?

    Solution

    java -cp cs1302-packages/bin HelloWorld

  4. Why do we use -cp bin instead of -cp src when running the program with java?

    Solution
    • The src/ directory contains your source code (.java files), not compiled bytecode.

    • The bin/ directory contains the compiled ``.class`` files generated by javac.

    • 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 the HelloWorld.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
  1. 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).

  2. Explain why the command fails.

    Solution

    Since we are inside the bin folder, the relative path to HelloWorld.java is incorrect. We are telling javac to look for the file src/HelloWorld.java relative to this directory, which does not exist.

  3. What would be the correct compile command from within bin?

    Solution
    javac -d . ../src/HelloWorld.java
    
  4. What would be the command to run HelloWorld from bin/?

    Solution

    Two possible solutions (of many):

    java HelloWorld
    
    java -cp . HelloWorld
    
  5. 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:

Listing 2.13 In Welcome.java
 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
  1. After saving and exiting Emacs, which folder contains Welcome.java?

    Solution

    The file Welcome.java is placed in java-tutorial since that is the directory we ran the emacs command from.

    The directory structure would look as follows:

    java-tutorial     // You are here
    ├── code
    ├── compiled
    └── Welcome.java
    
  2. 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:

Listing 2.14 You are in the parent directory of java-labs
// 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.

  1. 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 in src/com/tools/math/. Look for any required compiled classes in the bin directory (-cp bin), and store the resulting .class file in the correct package directory structure inside bin/ (-d bin).

  2. 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 in bin 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
  1. Explain why the .class files are stored in subdirectories under bin matching their package names.

    Solution

    The .class files are stored in subdirectories under bin that match their package names because the JVM and compiler use this folder hierarchy to map package names to filesystem locations.

  2. 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.

  3. 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 or ClassNotFoundException.