Section 5.3. The Java Compiler


5.3. The Java Compiler

At the heart of the SDK is javac, the Java compiler. The general form of javac follows:

 javac [option...] [sourcefile...] [@optfile...] 

The option list may be zero or more command-line options. We'll detail those later. The sourcefile list may be the name of zero or more Java source files. Usually you specify just the "main" class of an application. As we will describe later, javac generally will compile all necessary .java files for any classes that main() class references, directly or indirectly. If you prefix a filename with the at sign (@), the contents of the file will be treated as if they had been typed on the command line.

5.3.1. Compiler Behavior, Defaults, and Environment Variables

In the simplest casecompiling a single class, such as our FetchURL.java classyou 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 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.

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] $ 

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 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.

Example 5.3. Setting the CLASSPATH environment variable
 $ export CLASSPATH=/home/mschwarz/java/simpleApp:/var/java/lib/project.jar $ echo $CLASSPATH /home/mschwarz/java/simpleApp:/var/java/lib/project.jar $ 

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).

5.3.2. javac Options

The Java compiler has many command-line options that modify its behavior. We will go over the most important ones here. This is not a complete reference! See the Sun SDK Documentation for complete reference information.

-classpath

Sets the classpath. This overrides the CLASSPATH environment variable, if one is specified.

-d

This switch is followed by a directory name. Compiled classes are placed in that directory. Normally, compiled classes are placed in the same directory as the source code.

-deprecation

This causes every use or reference to a deprecated class or method to be displayed on compilation.[2]

[2] In Java, it is rare for APIs to break support for existing code. Rather than remove old methods, it is more common to deprecate them. This is done by putting a @deprecated tag in a Javadoc comment on the class or method. The Java compiler will issue a warning (if the -deprecated switch is on) whenever a deprecated class or method is used. In general, deprecation is a warning that the class or method will be removed in a future version of the code or library. It is interesting to note that the javac compiler records that a method or class is deprecated in the binary. Thus the compiler produces different output based on the contents of a comment. As we have written simple compilers and interpreters, this creeps us out. We have always wondered why deprecated has not become a Java language keyword.

-g

Put full debugging information in the compiled class files. See also -g: (the next entry in this list).

-g: keyword_list

This switch gives you fine-grained control over the amount of debug information included in compiled class files. The argument after the colon may be either none, in which case no debug information is included, or a comma-separated list with any combination of source, to include source file debugging information, lines, to include line number information, or vars, to include information about local variable names. The default, if no -g flag of any kind is specified, is to include source file and line number information only.

-nowarn

Disables warning messages.

-verbose

Causes the compiler to output information about each class encountered during compilation. This can be helpful when trying to resolve problems with missing class definitions.

There are also a number of switches that relate to cross-compiling as well as UNIX-specific options, but these are not commonly used. Refer to the Sun Java SDK Tools documentation if you need details on these options.



    Java Application Development with Linux
    Java Application Development on Linux
    ISBN: 013143697X
    EAN: 2147483647
    Year: 2004
    Pages: 292

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net