Env Classpath
**Using `javac -classpath`:**
**`javac`:** If the Java file you are currently compiling references other classes (for example, through inheritance), but the `.class` files of those referenced classes are not in the current directory, you need to add the `-classpath` parameter after the `javac` command. You can use one of the following three methods to guide the compiler to search for the referenced classes in the specified path during compilation.
* (1). Absolute path: `javac -classpath c:/junit3.8.1/junit.jar Xxx.java`
* (2). Relative path: `javac -classpath ../junit3.8.1/Junit.jar Xxx.java`
* (3). System variable: `javac -classpath %CLASSPATH% Xxx.java`
(Note: `%CLASSPATH%` indicates that the value of the system variable `CLASSPATH` is used for searching. It is assumed here that the path to `Junit.jar` is already included in the `CLASSPATH` system variable.)
**Using Absolute Paths with `javac`:**
`javac`: Suppose the class file you want to compile is named `HelloWorld.java`, and its full path is `D:/java/HelloWorld.java`. However, your current working directory is `C:/Documents and Settings/peng>`. What will happen if you try to compile it directly from this directory?
(1). **`C:/Documents and Settings/peng> javac HelloWorld.java`**
In this case, the compiler will display the following error message:
error: cannot read: HelloWorld.java
This happens because, by default, `javac` searches for class files in the current directory. Clearly, this is not where our class file is located, so an error occurs.
(2). **`C:/Documents and Settings/peng> javac D:/java/HelloWorld.java`**
Here, the compilation succeeds.
Therefore, whenever the directory where you run the `javac` command is different from the directory where the class file is stored, you must explicitly specify the class fileβs path in the `javac` command.
**Using `-classpath` with `java`:**
`java`: Assume our `CLASSPATH` is set to `D:/peng/java/pro`. In this directory, there are three files: `HelloWorld.java`, `HelloWorldExtendsTestCase`, and `HelloWorldExtendsHelloWorld`. Their respective class declarations are as follows:
- `HelloWorld.java`: `public class HelloWorld`
- `HelloWorldExtendsHelloWorld.java`: `public class HelloWorldExtendsHelloWorld extends HelloWorld`
- `HelloWorldExtendsTestCase.java`: `public class HelloWorldExtendsTestCase extends junit.framework.TestCase`
Suppose we have successfully compiled these three files using the techniques described above for `javac -classpath` and absolute paths. Now, letβs execute these three `.class` files from the directory `C:/Documents and Settings/peng>`.
**`C:/Documents and Settings/peng> java HelloWorld Hello World`**
The execution succeeds. Why can the JVM find the `D:/peng/java/pro/HelloWorld.class` file even though we are running the command from `C:/Documents and Settings/peng>`? This is because we configured the system variable `CLASSPATH` to point to the directory `D:/peng/java/pro`. As a result, the JVM defaults to loading class files from this directory without requiring us to specify the absolute path of the `.class` file.
**`C:/Documents and Settings/peng> java HelloWorldExtendsHelloWorld Hello World`**
This also executes successfully. Since `HelloWorldExtendsHelloWorld` inherits from `HelloWorld`, the JVM first checks whether a `HelloWorld.class` file exists under the `CLASSPATH`. Because we have already compiled the `HelloWorld` class, the execution of `HelloWorldExtendsHelloWorld.class` succeeds.
**`C:/Documents and Settings/peng> java HelloWorldExtendsTestCase`**
An exception occurs:
Exception in thread "main" java.lang.NoClassDefFoundError: junit/framework/TestCase
Why does `HelloWorldExtendsHelloWorld.class` execute successfully in the same directory (`/peng/java/pro`), while this one fails? The reason is that the `junit.framework.TestCase.class` file is not present in the current directory. To ensure successful execution, we must explicitly specify the `CLASSPATH` so that the JVM can locate the `junit.framework.TestCase` class, as shown below:
**`C:/Documents and Settings/peng> java -classpath %CLASSPATH% HelloWorldExtendsTestCase Hello World`**
Now, the program runs successfully.
**Summary:**
* (1). When to use `-classpath`: Whenever the class you are compiling or executing references other classes, but the `.class` files of those referenced classes are not in the current directory, you need to use `-classpath` to include them.
* (2). When to specify the path: If the directory containing the class file you want to compile is different from the directory where you are running the `javac` command, you must specify the source fileβs path. (Note: `CLASSPATH` is used to specify the location of `.class` files, not `.java` files.)
YouTip