< Zurück | Inhalt | Weiter >

5.3.1 Compiler Behavior, Defaults, and Environment Variables

In the simplest case—compiling a single class, such as our FetchURL.java

class—you get no diagnostics on success (Example 5.1).


Example 5.1 Compiling FetchURL.java

$ javac FetchURL.java



There will now be a new file, FetchURL.class, in the directory with the Java source file. Let’s run that again with a command-line option we will detail later (Example 5.2).

Boy, our single, simple, one-class application sure uses a lot of classes! It does. Where did they come from? They come from the classes referenced by


Example 5.2 Compiling FetchURL.java with the -verbose option

$ javac -verbose FetchURL.java [parsing started FetchURL.java] [parsing completed 479ms]

[loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/lang/Object.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/net/URL.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/lang/String.class)] [checking FetchURL]

[loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/lang/Exception.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/lang/Throwable.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/io/BufferedReader.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/io/InputStreamReader.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/net/URLConnection.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/io/Reader.class)]

[loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/io/InputStream.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/lang/System.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/io/PrintStream.class)]

[loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/io/FilterOutputStream.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/io/OutputStream.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/lang/Error.class)]

[loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/net/MalformedURLException.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/io/IOException.class)]

[loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/lang/RuntimeException.class)] [loading /usr/java/j2sdk1.4.1_02/jre/lib/rt.jar(java/lang/StringBuffer.class)] [wrote FetchURL.class]

[total 3469ms]



the application, either directly through composition or inheritance, or indirectly because the classes we used are themselves composed of or inherit from other classes. How did the Java compiler know where to find these classes? For this, it used what the Sun documentation calls a bootstrap classpath, which is set when the SDK is installed. A classpath is a list of directories and/or JAR files that are searched for classes. We seem to dimly recall that in early versions of Java, there was only one classpath, and if you changed it, you had to remember to put the Java runtime JAR file on it, or none of the standard APIs were available. This, no doubt, is why Sun created the concept of a bootstrap classpath. If you use any third party JAR files or you create your own, you must tell the compiler about it by creating your own classpath.

There are two ways to provide a classpath to the Java compiler. One is through a command-line switch, which we will cover in a moment. The other is through an environment variable. The CLASSPATH environment variable lists


Example 5.3 Setting the CLASSPATH environment variable

$ export CLASSPATH=/home/mschwarz/java/simpleApp:/var/java/lib/project.jar





directories and/or JAR or ZIP files that contain classes. Each directory or JAR file is separated from the others by a colon (“:”), as shown in Example 5.3.

The classpath for the compiler consists of the bootstrap classpath plus the user-specified classpath. What does the classpath mean in terms of Java class names? Think of the classpath as a list of “package roots.” In other words, when you refer to a class like java.sql.DriverManager or net.multitool.SAMoney, the Java compiler is going to go to each entry in the combined bootstrap-and-user classpath and check there for java/sql/DriverManager.class or net/multitool/SAMoney.class. If it doesn’t find the .class file in a candidate directory, it will look for the

.java file. If it finds the .java file, it will compile it and then use the resulting

.class file. When it has a .class file for the class, it stops searching the classpath. In this way, compiling the single “main” class of an application will often compile the whole application (we will get to exceptions to that rule later).