This file summarizes changes some changes to the way the Java 2 SDK's
tools work as compared to the tools that ship with the JDK 1.1.x software.
The changes described here are not changes between versions
1.2 and 1.3 of the Java 2 SDK.
This document summarizes a few important changes in command line options
between JDK1.1 and Java 2 SDK 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 the
Java 2 SDK tools 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.
The class path has a default value and can be set by -classpath
or CLASSPATH. In 1.1, it worked as follows:
Class path default - The default value of the class path was (1) the path where Java
platform classes resided (classes.zip or
rt.jar), and (2) the current working directory (".",
read as "dot").
CLASSPATH - If the environment variable CLASSPATH was set, then
the class path would (1) continue to contain classes.zip or
rt.jar just the like default plus (2) the newly set
value instead of the current working directory. [See Note 1]
-classpath - If the option -classpath <path> was used, then
<path> had to explicitly contain both (1)
classes.zip or rt.jarand
(2) application classes.
This behavior for -classpath was unfortunate because
it meant users had to spell out the path to classes.zip:
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 as used in
the Java 2 SDK tools has taken on the same meaning as the CLASSPATH
environment variable in the Java 2 SDK, so you can now conveniently omit
having to spell out the path to Java platform classes:
C:> java -classpath C:\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 the Java 2 SDK, 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 the Java 2 SDK.
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.
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 the Java 2 SDK, there are three search paths that are used to find
classes:
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.
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").
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.
With the Java 2 SDK tools, 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.
-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:
In this example, the java command searches
the paths provided by -Xbootclasspath
to find the Java platform classes.
It first searches the directory C:\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
C:\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 the Java 2 SDK's 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:
Avoid overriding Java platform classes -
The Java 2 Runtime Environment's re-distribution license does not allow replacing parts
of rt.jar. So the -Xbootclasspath option
may not be used override parts of rt.jar when
you are re-distributing the Runtime Environment with an application. When
re-distributing, if there is a need to place your application on the
bootclasspath, we recommend using the
oldjava command. If you are not
using oldjava, then make sure that unmodified
rt.jar and (the optional) i18n.jar, are
placed first on -Xbootclasspath before your application classes.
For example:
# If app needs to be deployed on -Xbootclasspath, then use:
C:> java -Xbootclasspath:C:\jre\lib\rt.jar;C:\app\classes Application
# instead of accidentally overriding rt.jar:
C:> java -Xbootclasspath:C:\app\classes;C:\jre\lib\rt.jar Application
Our implementation of class path searching -
The discerning reader is bound to ask "How are all these paths
tied together by the implementation of java?" We'll
resist the temptatation to say, "the answer is beyond the scope of
this document," but instead present a short version of the story.
The Java 2 Platform introduced the notion of a parent classloader. A
well-behaved classloader in the Java 2 Platform always checks to see if its parent
can load the class before it uses its own mechanisms (such as paths
it might have been asked to look at) to locate a class.
The Java runtime has three classloaders, where a
parent classloader is shown above its child:
The bootstrap classloader searches for classes only on the
bootclasspath and on no other path. Likewise, the extension
classloader searches in the extensions loaded from extdirs,
and the application classloader searches only on the application
class path.
Say, you launch your application with the following command line:
C:> java -classpath C:\my\classes MyApplication
This command causes a sequence of steps, giving each classloader
in turn a chance to load the application classes. First, the
java command asks the application classloader
(the one that uses the -classpath value) to load
MyApplication. However, rather than trying to load
this class, the application classloader asks its parent, the
extension classloader, to load the class, which in turn,
likewise asks its parent, the bootstrap classloader, to load the
class. The bootstrap classloader is built into the virtual machine
and has no parent; it attempts to load the class from the
bootstrap classpath. Since the bootstrap classloader will not
find MyApplication (we did not use
-Xbootclasspath to disturb the default path),
it allows the extension classloader to try to load the class,
which also will not find the class (since we did not use
-Djava.ext.dirs options to disturb the default
path). Finally, the application classloader ends up finding
and loading C:\my\classes\MyApplication.class.
It is such parenting that produces the order "bootstrap
first, extensions next, applications last" when searching for
classes. For more information we again refer you to the
The
Extensions Framework documentation.
In the Java 2 SDK, 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 with the Java 2 SDK. 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.
C:> dir \home\user\htmls \home\user\classes
C:\home\user\classes:
Foo.class
C:\home\user\htmls:
foo.html
# Foo.class is NOT in applet's codebase:
C:> type \home\user\htmls\foo.html
<applet code=Foo height=100 width=100></applet>
# Can an applet use a class outside its codebase?
C:> set CLASSPATH=C:\home\user\classes
# Works in 1.1.
C:> appletviewer \home\user\htmls\foo.html
# ClassNotFoundException with the Java 2 SDK!
C:> 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 the Java 2 SDK. The classes
referred to by an applet must be either:
Java platform classes (such as
java.lang.String) which
are present in a browser, or,
classes that can be downloaded from the applet's
codebase.
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 the Java 2 SDK, we recommend the use of
The
Extensions Framework, which, unlike CLASSPATH, is a
deployment solution. (CLASSPATH is only a
development time solution.)
In the Java 2 SDK tools, 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:
C:> java -ms10m Application
In the Java 2 SDK, you should express the same option with a
-X.
C:> java -Xms10m Application
The motivation here, as you probably guessed, is that the Java 2 SDK tools
distinguishe 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 Java 2 SDK's
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:
C:> java -help
C:> javac -help
For the current list of non-standard options, please type:
C:> java -X
C:> 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.
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:
C:> dir \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
C:> javac \tmp\foo\bar\FooBar.java
\tmp\foo\bar\FooBar.java:3: Superclass foo.bar.Helper of ... not found.
C:> set CLASSPATH=\tmp
# Works because javac snooped in CLASSPATH for source files
C:> javac \tmp\foo\bar\FooBar.java
In the Java 2 SDK, 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:
C:> set CLASSPATH=\tmp
# This still works with the Java 2 SDK:
C:> javac \tmp\foo\bar\FooBar.java
# But it doesn't work if you use -sourcepath
C:> javac -sourcepath . \tmp\foo\bar\FooBar.java
\tmp\foo\bar\FooBar.java:3: Superclass foo.bar.Helper ... not found.