2.5. Code Dependencies

Important

This section picks up where the last section left off. You should start by logging into Odin and changing directories into the cs1302-packages directory you created while working through that tutorial and make sure your files are still intact.

In the previous section you compiled and ran code that you placed into a named package. In that section, you were working with a single Java file. In this section, we will compile and run an application that depends on code in multiple Java files.

When one Java file requires access to another file to run, it is called a code dependency (or dependency for short). When there are dependencies in our projects, we need to make sure to consider these dependencies when compiling and running our code. As our applications get larger and contain more .java files, this becomes even more important to consider. This section will walk you through this process.

Most of the programs that you have written have used code provided by Oracle under the various java subpackages. When you compile, those dependencies are automatically included on the classpath. However, when your code depends on code that’s not included with Java (e.g., code that you or someone else has written), you need to let javac know where the compiled version of that dependency is. Remember the classpath (-cp) option we used when compiling and running our code in the last section? This will be very similar.

  1. Let’s extend the code we wrote in the previous tutorial by creating a class called cs1302.util.HelloUtility.

    Test Yourself

    Based on the FQN of the class we are creating (cs1302.util.HelloUtility), answer the following questions:

    1. What is the simple class name?

    2. What is its package?

    3. What directory should contain the HelloUtility.java file?

    4. Will you need to create any new directories?

    5. What should be the first line in the HelloUtility.java file?

    Test Yourself Solution (Don’t open until after answering questions above)
    1. HelloUtility

    2. cs1302.util

    3. The file will need to be placed in the src/cs1302/util directory within the cs1302-packages directory. In this example, src represents our top-level (default) directory for source code and the cs1302 and util directories are our package directories that correspond to the name of the packages.

    4. Yes, we will need to create the util directory under src since it doesn’t already exist.

    5. package cs1302.util

  2. Write the code to declare the cs1302.util.HelloUtility class, including the proper class declaration and package statement at the top. Then, within the class declaration, add the following method:

    // Don't forget your package statement up here!
    public class HelloUtility {
        public static void excitingHello() {
            System.out.println("HELLO!!!!");
        } // excitingHello
    } // HelloUtility
    
  3. Save, exit Emacs, then compile the .java file for the cs1302.util.HelloUtility class as usual, using bin as the destination for the compiled code. Once it compiles, make sure that the output from tree matches the output below:

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

    The output of the ``tree`` command after compiling our new file.
  4. Now, modify the source code for your cs1302.hello.HelloWorld class to call the static method in cs1302.util.HelloUtility. To do this, you may:

    1. Add an import statement between the package statement and class declaration:

      import cs1302.util.HelloUtility;
      
    2. Call the method in main using the simple class name:

      HelloUtility.excitingHello();
      

    Completing these two steps creates a dependency. Now, the cs1302.hello.HelloWorld class depends on the cs1302.util.HelloUtility class because it uses a method defined within that class.

  5. In the last section, we used the command:

    This command will not work now. Explanation below.
    javac -d bin src/cs1302/hello/HelloWorld.java
    

    However, this command will not work now because of the dependency. Remember, HelloWorld is now dependent on HelloUtility, so the compiler will not be able to compile HelloWorld unless you also tell it where to find HelloUtility. Do you remember how to tell the Java where to look for the class we wanted it to run using -cp? Here, we will need to do the same thing - except when we are compiling.

    Here is our new command:

    If you are not in the cs1302-packages directory, this command will not work.
    javac -cp bin -d bin src/cs1302/hello/HelloWorld.java
    

    Understanding the Command

    In English, this command tells the Java compiler to: “compile the HelloWorld.java file located in the src/cs1302/hello directory and place the resulting .class file in the bin folder. Also, if there are any dependencies to any other .class files, look in the bin directory to find those files.

    Now it works! The compiler will check the bin folder and find the HelloUtility class in the cs1302.util folder within bin.

    Remember that when your code depends on other code that you have written, you need to let javac know where the compiled version of that dependency is. Since you compiled under bin, that’s where you should tell javac to look.

    With the addition of -cp bin, it will be able to find the HelloUtility class that it is dependent on.

  6. Run the code to make sure it works. Since we’re running the HelloWorld class (it has the main method), the command to run will not change from the previous section. Remember, the basic idea is to use the java command along with the FQN of the class you want to run. You will also need -cp to tell Java where to find the class to run.

Here is a video outlining the steps in this section if you get stuck: