CLASSPATH, -classpath, -d


CLASSPATH is an environment variable which tells javac or java where to find the user defined classes it must refer to.CLASSPATH consists of a colon separated list of directories. The directory containing Java system classes will be automatically appended at the end of the list by the system.

-classpath is an option for javac or java which is used to specify the directories for where to find the referred user-defined classes. What -classpath specified can override $CLASSPATH.

-d is an option for javac which is used to specify where is root directory to store the compiled java binary files.

In our tutorial, we will store our Java source files and compiled class files in separate directories. We will use ~/jjava/source to store our Java source files, and use ~/jjava/class as the root directory to store our self-defined classes.

================== Practice =======================

Change the current working directory to the source file directory :

For this section, we will use Java sample programs in the directory of ~/jjava/source/TimeClasspath/. Under it there are two directories and each of them contains one file. The two files are: ~/jjava/source/TimeClasspath/component/Time.java, which defines a class Time, ~/jjava/source/TimeClasspath/main/TimeTest.java which is the main testing program utilizing Time.java.

cd ~/jjava/source/TimeClasspath<cr>--there are two files, component//Time.java and main/TimeTest.java.

Compile Java program using -d option:

To store Java source files and compiled bytecode files in separated directories, for sure we can use javac in the source code directory in the same way as what we have used before i.e. javac Time.java<cr>, produce the .class files there and then move them to the directory for class file, but javac has an option, -d, to help:

cd component<cr> OR cd ~/jjava/source/TimeClasspath/component<cr>---go to ~/jjava/source/TimeClasspath/component/, which contains Time.java.

javac -d ~/jjava/class Time.java<cr> --compile Time.java and stored the output bytecode files Time.class in directory ~/jjava/class/.

Compile Java program using -classpath option:

cd ../main<cr> OR cd ~/jjava/source/TimeClasspath/main<cr> ---go to ~/jjava/source/TimeClasspath/main/, which contains TimeTest.java.

javac -classpath ~/jjava/class -d ~/jjava/class TimeTest.java<cr>--This command tells the javac to compile TimeTest.java and put the resulted bytecodes in ~/jjava/class/. If need some class files, find them in the directories speified after -classapth. Since in our case, compile TimeTest.java needs to use Time.java or Time.class, this command tells javac to looks Time.java or Time.class in ~/jjava/class/.

If you run command: javac -d ~/jjava/class TimeTest.java<cr>, you will get error messages since javac can not find either Time.java or Time.class in the current working directory. If TimeTest.java and Time.java are both in the current working directory, this command will compile both source files and put the two bytecode files in ~/jjava/class.

java also find other necessary classes in Java system's default class path.

Run the java program:

After compile and stored all classes into directory ~/jjava/class/, we can always go to that directory to run TimeTest.class using the same command as we did before. The steps would be 1. cd ~/jjava/class<cr>. 2. java TimeTest<cr>. java has -classpath option, which allows you to run a bytecode files in a different directory.

java -classpath ~/jjava/class TimeTest<cr> --java will run TimeTest.class by finding TimeTest.class and the necessary Time.class in ~/jjava/class/.

If the necessary class files are in several directories, you can list them after -classpath by separating each of them with a ":". For example: java -classpath ./:~/jjava/class:/u0/robert/myclasses TimeTest<cr>

Set environment variable CLASSPATH:

Getting tired of typing -classpath ~/jjava/class? You can set a value for Unix environment variable CLASSPATH. After CLASSPATH is set, java or javac will try to look for the necessary class files into the directories of $CLASSPATH.

setenv CLASSPATH ~/jjava/class<cr>
--this command is for tcsh. For bash, use: export CLASSPATH=~/jjava/class<cr>

echo $CLASSPATH<cr> --check the value of CLASSPATH.

Compile and run Java programs after CLASSPATH is set:

Now you can go to ~/jjava/class directory to delete all .class files. We will re-compile and run the Java programs with CLASSPATH being set.

cd ~/jjava/source/TimeClasspath/component<cr>

javac -d $CLASSPATH Time.java<cr>--compile Time.java and put Time.class into the directory of $CLASSPATH. You have the choice to put the resulted .class file in other directories.

cd ../main<cr>

javac -d $CLASSPATH TimeTest.java<cr>--compile TimeTest.java. With CLASSPATH being set, javac can find Time.class in $CLASSPATH.

java TimeTest<cr> --With CLASSPATH being set, java can find TimeTest.class and Time.class in $CLASSPATH.

NOTE: with CLASSPATH being set, you can still use -classpath option with javac and java to override $CLASSPATH.

Summary:

  1. It is a good practice to organize the classes and source files in different directories.
  2. Set the environment variable CLASSPATH to the root directory where class files will be stored.
  3. When compile, use -d $CLASSPATH option to store the class files in the appropriate directories.
  4. Then you can use the following format to compile and run Java programs:

javac -d $CLASSPATH ClassName.java<cr>
java ClassName<cr>

--otherwise you may have to play with -d and -classpath options with javac and play -classpath option with java.