Command Line Changes From 1.1 to 1.2

JDK Tools

Introduction

This document summarizes a few important changes in command line options between JDK1.1 and JDK1.2 tools. Its target audience is those already familiar with the command line options of JDK1.1 tools.

Please note that every effort has been made to keep the options in JDK1.2 backwards compatible with the options in JDK1.1, where possible. The purpose of this document is to provide you with a quick overview of what has changed, and to outline the motivation behind the changes. We hope that understanding our motivations will help you better use the new features.

Throughout this document we use the term "Java platform classes" to refer to classes that belong to the Java platform, as specified in the Java API Specification, such as ava.lang.String. These reside in classes.zip or rt.jar. We also use the term "class path" to refer to the search path set by CLASSPATH and -classpath (which has a different meaning in 1.1 and 1.2).

Although the examples in this document are Solaris oriented, they apply equally to Windows, after the slashes and prompts have been appropriately changed.

Changes to CLASSPATH and -classpath

The class path has a default value and can be set by -classpath or CLASSPATH. In 1.1, it worked as follows:

This behavior for -classpath was unfortunate because it meant users had to spell out the path to classes.zip:
 % java -classpath /jdk-path/lib/classes.zip:/app/classes Application
We say unfortunate because this is inherently error-prone; the onus is on the user to ensure that the java command and the classes.zip were from the same JDK version. We ourselves have spent time debugging problems where a 1.1.4 java was trying to run 1.1.3 classes.zip, and this does not work because the native methods do not match.

The good news is that the -classpath option in 1.2 has taken on the same meaning as the CLASSPATH environment variable in 1.2, so you can now conveniently omit having to spell out the path to Java platform classes:

 % java -classpath /app/classes Application

Some developers like to temporarily modify individual Java platform classes such as java/util/Vector.class, for purposes such as adding println statements to understand how the class works. In 1.2, these users would not be able to use the -classpath option to set the path to Java platform classes, as was possible in 1.1. For such uses, the -Xbootclasspath option must be used in 1.2.

Note 1 - Contrary to the bulleted statement above, we have seen users explicitly placing the path to classes.zip in their CLASSPATH environment variable, though this was not at all required.

New Class Search Paths

The earlier section showed that in JDK1.1, there was one search path used to find classes; its value could be set either through the -classpath option or the CLASSPATH environment variable.

In JDK 1.2, there are three search paths that are used to find classes:

  1. The first place where java looks for classes is the bootstrap classpath. The value of this path can be examined by calling System.getProperty("sun.boot.class.path"). Note that the prefix "sun." shows that, at least for now, this property is specific to Sun's implementation.
  2. The second place where java looks for classes is the extension directories. The list of directories can be examined by calling System.getProperty("java.ext.dirs").
  3. The third and last place where java looks for classes is the application classpath. The value of this path can be examined by calling System.getProperty("java.class.path").

For a discussion of the new "extension directories" feature mentioned in item 2, refer to javac and The Extensions Framework documentation.

In 1.2, the argument you specify with the -classpath option is the value of the application classpath; it should contain the path to classes that constitute your application. The bootstrap classpath contains the path to Java platform classes that are contained in a file named rt.jar. This is discussed in the next section.

New Options to Search for Boot Classes: -Xbootclasspath, -bootclasspath

NOTE - For a description of what the leading "X" means in an option, see Standard vs. Non-standard Options.
-Xbootclasspath - As mentioned, the bootstrap classpath contains the path to Java platform classes that are contained in rt.jar. If you need to override the location where Java platform classes are found, you must use the -Xbootclasspath option -- this is a big change from 1.1 where -classpath provided this functionality. Consider this example:
 % java -Xbootclasspath:/my/bootclasses:/jre/lib/rt.jar MyApplication 

In this example, the java command searches the paths provided by -Xbootclasspath to find the Java platform classes. It first searches the directory /my/bootclasses before searching through rt.jar. If you wanted to add debugging statements to java/util/Vector.class, you would place the modified class file under /my/bootclasses. This modified version would be found first, the search would then stop and this version would be loaded.

-bootclasspath - In addition, javac supports a similar option -bootclasspath which can be used to change the platform classes you are compiling against. This is most useful if you need to take advantage of the bug fixes in 1.2 javac to compile a 1.1 application. Please refer to that option for detailed instructions on how to do this.

Here are some relevant notes for both options:

oldjava

oldjava

Appletviewer No Longer Uses CLASSPATH

In JDK 1.2, appletviewer ignores your CLASSPATH environment setting (which it did not ignore in 1.1). Though this sounds like a drastic change, this is the semantics you really want when testing your applets.

Let us consider an example that worked in JDK 1.1, but will not work in JDK 1.2. Say you placed your .html file in a place different from your .class files. In JDK 1.1, you could set your CLASSPATH at the .class files, and appletviewer would pick them up.

   # Foo.class and foo.html are in different directories.
   % ls /home/user/htmls /home/user/classes 
   /home/user/classes:
   Foo.class
     
   /home/user/htmls:
   foo.html

   # Foo.class is NOT in applet's codebase:
   % cat /home/user/htmls/foo.html
   <applet code=Foo height=100 width=100></applet>

   # Can an applet use a class outside its codebase?
   % setenv CLASSPATH /home/user/classes

   # Works in 1.1.
   % /1.1.7/bin/appletviewer /home/user/htmls/foo.html

   # ClassNotFoundException in 1.2!
   % /1.2/bin/appletviewer /home/user/htmls/foo.html

Why did we change what looks like reasonable behavior? Look more closely. When an applet runs in a browser which does not honor CLASSPATH the way JDK's appletviewer does, you have the same problem that you have when using 1.2. The classes referred to by an applet must be either:

You cannot, and should not, expect a user of your applet to set their CLASSPATH, and even if they did, their browser might choose to ignore it. Consequently, appletviewer now does the same thing that a browser would.

One nice thing about 1.1 appletviewer honoring CLASSPATH was that you could grab a third party library (say a mailx.jar providing some email related functionality), place it on your CLASSPATH and your applet could refer to the classes in mailx.jar. In order to get the same convenience in JDK 1.2, we recommend the use of The Extensions Framework, which, unlike CLASSPATH, is a deployment solution. (CLASSPATH is only a development time solution.)

Standard vs. Non-standard Options

In 1.2 some options are prefixed with -X whereas others are not. In 1.1, if you needed to set the startup heap size of the virtual machine to 10MB, you would say:

    % java -ms10m Application

In 1.2, we recommend that you express the same option with a -X.

    % java -Xms10m Application

The motivation here, as you probably guessed, is that 1.2 distinguishes between options that can apply to all virtual machines, as opposed to options that are specific to a particular virtual machine's implementation. We expect all virtual machines will allow setting a classpath, but we can't expect all virtual machines to support initial heap size.

In the long run, as more compiler and virtual machine vendors support the same standard options, replacing a compiler won't require any changes to your makefiles, or replacing a virtual machine for a server application you launched through a script will need no modifications to the script.

Note however that for backwards compatibility, the 1.2 java launcher internally translates -ms10m to -Xms10m, so you could still use the old -ms10m option, but we recommend that you do use the newer syntax.

For the current list of standard options, please type:

    % java -help
    % javac -help

For the current list of non-standard options, please type:

    % java -X
    % javac -X

A note to vendors -- this separation of command line options into standard and non-standard ones is orthogonal to, and bears no relation with, conformance requirements. As stated earlier, we just hope that users' lives will be eased in the long run if standard options become a de facto standard for options that makes sense.

New Option to Search for Source Files: -sourcepath

In 1.1, javac and javadoc would find both source files and class files in the paths specified in the CLASSPATH environment variable. For example, suppose you compiled foo/bar/FooBar.java and the class FooBar relied on a Helper class, then javac would attempt to find the source file Helper.java in your CLASSPATH:
    % ls /tmp/foo/bar/*.java
    /tmp/foo/bar/FooBar.java   /tmp/foo/bar/Helper.java

    # Error because javac can't find Helper.class or Helper.java
    % /1.1.7/bin/javac /tmp/foo/bar/FooBar.java
    /tmp/foo/bar/FooBar.java:3: Superclass foo.bar.Helper of ... not found.

    % setenv CLASSPATH /tmp

    # Works because javac snooped in CLASSPATH for source files
    % /1.1.7/bin/javac /tmp/foo/bar/FooBar.java
In 1.2, these tools still look in CLASSPATH for source files unless the -sourcepath <path> option is included -- then it looks only in <path> for source files, and the CLASSPATH is not searched for source files:
    % setenv CLASSPATH /tmp

    # This still works in 1.2: 
    % /1.2/bin/javac /tmp/foo/bar/FooBar.java

    # But it doesn't work if you use -sourcepath
    % /1.2/bin/javac -sourcepath . /tmp/foo/bar/FooBar.java
    /tmp/foo/bar/FooBar.java:3: Superclass foo.bar.Helper ... not found.


Last modified: Thu Nov 19 10:23:16 PST