C:\temp\packagea\ClassA.java
/tmp/packagea/ClassA.java
C:\temp\packageb\ClassB.java
/tmp/packageb/ClassB.java
cd C:\temp
cd /tmp
Now it is time to compile the code. Luckily, this is the same regardless of the operating system. To compile, type the following command:
javac packagea/ClassA.java packageb/ClassB.java
If this command doesn't work, you'll get an error message. Check your files carefully for typos against the provided files. If the command does work, two new files will be created: packagea/ClassA.class
and packageb/ClassB.class
.
Compiling with Wildcards
You can use an asterisk to specify that you'd like to include all Java files in a directory. This is convenient when you have a lot of files in a package. We can rewrite the previous javac
command like this:
javac packagea/*.java packageb/*.java
However, you cannot use a wildcard to include subdirectories. If you were to write javac *.java
, the code in the packages would not be picked up.
Now that your code has compiled, you can run it by typing the following command:
java packageb.ClassB
If it works, you'll see Got it
printed. You might have noticed that we typed ClassB
rather than ClassB.class
. As discussed earlier, you don't pass the extension when running a program.
Figure 1.1 shows where the .class
files were created in the directory structure.
FIGURE 1.1 Compiling with packages
Compiling to Another Directory
By default, the javac
command places the compiled classes in the same directory as the source code. It also provides an option to place the class files into a different directory. The -d
option specifies this target directory.
-D
instead of -d
.
If you are following along, delete the ClassA.class
and ClassB.class
files that were created in the previous section. Where do you think this command will create the file ClassA.class
?
javac -d classes packagea/ClassA.java packageb/ClassB.java
The correct answer is in classes/packagea/ClassA.class
. The package structure is preserved under the requested target directory. Figure 1.2 shows this new structure.
FIGURE 1.2 Compiling with packages and directories
To run the program, you specify the classpath so Java knows where to find the classes. There are three options you can use. All three of these do the same thing:
java -cp classes packageb.ClassB java -classpath classes packageb.ClassB java --class-path classes packageb.ClassB
Notice that the last one requires two dashes (--
), while the first two require one dash (-
). If you have the wrong number of dashes, the program will not run.
Three Classpath Options
You might wonder why there are three options for the classpath. The -cp
option is the short form. Developers frequently choose the short form because we are lazy typists. The -classpath
and --class-path
versions can be clearer to read but require more typing.
Table 1.2 and Table 1.3 review the options you need to know for the exam. There are many other options available! And in Chapter 12, “Modules,” you learn additional options specific to modules.
TABLE 1.2 Important javac
options
Option | Description |
---|---|
-cp <classpath> -classpath <classpath> --class-path <classpath>
|
Location of classes needed to compile the program |
-d <dir>
|
Directory in which to place generated class files |
TABLE 1.3 Important java
options
Option | Description |
---|---|
-cp <classpath> -classpath <classpath> --class-path <classpath>
|
Location of classes needed to run the program |
Compiling with JAR Files
Just like the classes
directory in the previous example, you can also specify the location of the other files explicitly using a classpath. This technique is useful when the class files are located elsewhere or in special JAR files. A Java archive (JAR) file is like a ZIP file of mainly Java class files.
On Windows, you type the following:
java -cp ".;C:\temp\someOtherLocation;c:\temp\myJar.jar" myPackage.MyClass
And on macOS/Linux, you type this:
java -cp ".:/tmp/someOtherLocation:/tmp/myJar.jar" myPackage.MyClass
The period (.
) indicates that you want to include the current directory in the classpath. The rest of the command says to look for loose class files (or packages) in someOtherLocation
and within myJar.jar
. Windows uses semicolons (;
) to separate parts of the classpath; other operating systems use colons.
Just like when you're compiling, you can use a wildcard (*
) to match all the JARs in a directory. Here's an example: