JDKTM 1.1 ツールと JavaTM 2 SDK ツールの
コマンド行の相違点

SDK ツール
ここでは、Java 2 SDK のツールと JDK 1.1.x ソフトウェアに付属しているツールの動作を比較して、変更点の概要について説明します。ここで説明する変更点は、Java 2 SDK のバージョン 1.2 と 1.3 の間の変更ではありません。

目次

はじめに

ここでは、JDK1.1 と Java 2 SDK ツールのコマンド行オプションの相違点のうち、いくつか重要な点について説明します。JDK1.1 ツールのコマンド行オプションをすでに理解しているユーザを対象としています。

Java 2 SDK ツールのオプションでは、できる限り JDK 1.1 のオプションに対する下位互換性を保つようにしてあります。このドキュメントの目的は、変更点、および変更理由の概略を説明することです。変更の理由を理解して、新しい機能のより効果的な利用に役立ててください。

このドキュメントでは、Java API の仕様で指定されているように、java.lang.String などの Java プラットフォームに属するクラスを指して、「Java プラットフォームクラス」という用語を使います。これらのクラスは、classes.zip または rt.jar 内にあります。また、CLASSPATH および -classpath によって設定される検索パスを指して、「クラスパス」という用語を使います。

このドキュメント内で紹介する例は Solaris 向けですが、スラッシュとプロンプトを適切に変更すれば、Windows にも同様に適用できます。

CLASSPATH および -classpath の変更

クラスパスにはデフォルト値があり、-classpath または CLASSPATH を使って設定できます。1.1 では、クラスパスは次のように機能しました。

この -classpath の動作は、ユーザが classes.zip へのパスを入力する必要があったため、問題になる可能性がありました。
% java -classpath /sdk-path/lib/classes.zip:/app/classes Application
問題になる可能性とは、この動作は本質的にエラー発生の可能性を含んでいるということです。 つまり、ユーザの責任において、同じバージョンの JDK の java コマンドと classes.zip を使う必要がありました。開発チームでも、1.1.4 の java で 1.1.3 の classes.zip を実行する箇所の問題のデバッグに努めましたが、ネイティブメソッドが一致しないため不可能でした。

Java 2 SDK ツールによって使用される -classpath オプションは、Java 2 SDK の CLASSPATH 環境変数と同じ意味を持つので、Java プラットフォームクラスへのパスを入力する必要がなくなり、便利になりました。

% java -classpath /app/classes Application

開発者によっては、println 文を追加してクラスの動作方法がわかるようにするために、java/util/Vector.class などの個々の Java プラットフォームクラスを一時的に修正したい場合があります。Java 2 プラットフォームでは、1.1 とは異なり -classpath オプションを使って Java プラットフォームクラスへのパスを設定することはできません。このような場合、Java 2 SDK では -Xbootclasspath オプションを使う必要があります。

注 1 - 上記の箇条書きに反して、CLASSPATH 環境変数に classes.zip へのパスを明示的に指定しているユーザもいますが、これはまったく必要ありません。

新しいクラス検索パス

前のセクションでは、JDK 1.1 にはクラスの検索に使う検索パスが 1 つあり、その値は -classpath オプション、または CLASSPATH 環境変数によって設定できることを示しました。

Java 2 SDK では、クラスの検索に使う検索パスは 3 つあります。

  1. java が最初にクラスを検索する場所は、ブートストラップクラスパスです。このパスの値は、System.getProperty("sun.boot.class.path") を呼び出して調べることができます。なお、接頭辞 sun. は、少なくとも現在のところは、このプロパティが Sun の実装特有のものであることを示します。
  2. java が次にクラスを検索する場所は、拡張機能ディレクトリです。ディレクトリの一覧は、System.getProperty("java.ext.dirs") を呼び出して調べることができます。
  3. java が 3 番目にクラスを検索する場所は、アプリケーションクラスパスです。このパスの値は、System.getProperty("java.class.path") を呼び出して調べることができます。

項目 2 の新しい「拡張機能ディレクトリ」機能については、javac の説明および 「Java 拡張機能機構」を参照してください。

Java 2 SDK では、-classpath オプションとともに指定する引数は、「アプリケーションクラスパス」の値で、アプリケーションを構成するクラスのパスを含んでいる必要があります。「ブートストラップクラスパス」は、rt.jar というファイルに含まれた Java プラットフォームクラスへのパスを含みます。これについては、次のセクションで説明します。

ブートクラス検索用の新しいオプション: -Xbootclasspath-bootclasspath

注 - オプションの先頭の「X」の意味については、「標準オプションと非標準オプション」を参照してください。
-Xbootclasspath - すでに説明したとおり、「ブートストラップクラスパス」は、rt.jar に含まれた Java プラットフォームクラスへのパスを含みます。Java プラットフォームクラスが見つかった位置をオーバーライドする必要がある場合は、-Xbootclasspath オプションを使わなければなりません。 これは、-classpath がこの機能を提供していた 1.1 からの大きな変更点です。次に例を示します。
% java -Xbootclasspath:/my/bootclasses:/jre/lib/rt.jar MyApplication

この例では、java コマンドで -Xbootclasspath によって提供されたパスを探し、Java プラットフォームクラスを見つけます。 rt.jar 内を検索する前に、まず、/my/bootclasses ディレクトリを検索します。java/util/Vector.class にデバッグ文を追加する場合は、修正したクラスファイルを /my/bootclasses の下に置きます。この修正版のファイルが最初に見つけられ、検索が終了し、修正版がロードされます。

-bootclasspath - さらに、javac は、コンパイルを行うプラットフォームクラスの変更に使用できる同様のオプション -bootclasspath をサポートしています。このオプションは、バグが修正された Java 2 SDK の javac を利用して 1.1 のアプリケーションをコンパイルするときにもっとも便利です。詳しい方法については、このオプションの説明を参照してください。

以下は、両方のオプションに関連した注意事項です。

CLASSPATH を使わなくなった appletviewer

appletviewer は 1.1 では CLASSPATH 環境設定を無視しませんでしたが、Java 2 SDK では無視します。これは、思い切った変更のようですが、アプレットのテスト時には必要なセマンティクスです。

JDK 1.1 では動作し、Java 2 SDK では動作しなくなった例を考えてみます。.html ファイルを .class ファイルとは別の場所に置いたとします。JDK 1.1 では、CLASSPATH.class ファイルに設定でき、appletviewer はそれを認識しました。

   # 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.
   % appletviewer /home/user/htmls/foo.html

   # ClassNotFoundException in the Java 2 SDK!
   % appletviewer /home/user/htmls/foo.html

正常に見える動作を変更したのは、なぜでしょうか。 SDK の appletviewer とは異なり、CLASSPATH が優先されないブラウザでアプレットが実行された場合、Java 2 SDK を使った場合と同じ問題が発生するためです。アプレットによって参照されるクラスは、次のどちらかである必要があります。

アプレットのユーザが CLASSPATH を設定することを前提にはできません。 たとえ、ユーザが CLASSPATH を設定したとしても、ブラウザによって無視される可能性もあります。このため、1.2 では、appletviewer はブラウザと同じことを行います。

CLASSPATH を優先する 1.1 の appletviewer には長所もありました。 たとえば、電子メール関連の機能を提供する mailx.jar などのサードパーティのライブラリを取得して CLASSPATH 上に配置すると、アプレットで mailx.jar 内のクラスを参照できたことです。Java 2 SDK で同じ便宜性を保つためには、Java 拡張機能機構の使用をお勧めします。(拡張機能機構は、「開発」時だけのソリューションである CLASSPATH とは異なり、配置用のソリューションです。

標準オプションと非標準オプション

Java 2 SDK ツールでは、-X という接頭辞が付いているオプションと付いていないオプションがあります。1.1 では、Virtual Machine の起動ヒープサイズを 10M バイトに設定する必要があった場合、次のように指定しました。

    % java -ms10m Application

Java 2 SDK では、-X を付けて同じオプションを表現します。

    % java -Xms10m Application

この目的は、Java 2 SDK ツールでは、すべての Virtual Machine に適用できるオプションと、特定の Virtual Machine の実装に特有のオプションとを区別することです。すべての Virtual Machine でクラスパスの設定が可能であることを前提としていますが、すべての Virtual Machine で初期ヒープサイズをサポートすることは前提にしていません。

コンパイラおよび Virtual Machine のベンダーが同じ標準オプションをサポートするようになり、最終的には、コンパイラを交換しても Makefile を変更する必要がなくなり、スクリプトを使って起動するサーバアプリケーション用の Virtual Machine を交換してもスクリプトを修正する必要がなくなります。

下位互換性維持のために、Java 2 SDK の java 起動ツールは、内部で -ms10m-Xms10m に変換するので、古い -ms10m オプションを使うこともできますが、新しい構文を使うことをお勧めします。

現時点の標準オプションの一覧を表示するには、次のように入力します。

    % java -help
    % javac -help

現時点の非標準オプションの一覧を表示するには、次のように入力します。

    % java -X
    % javac -X

ベンダーの方々へ -- この標準と非標準のコマンド行オプションの区分は、規格適合要件とは別の問題です。前述したように、将来的に標準オプションがオプションの事実上の規格になった場合に、ユーザの作業が楽になるようにするためのものです。

ソースファイルを検索するための新しいオプション: -sourcepath

1.1 では、javac および javadoc は、ソースファイルとクラスファイルのどちらも、CLASSPATH 環境変数に指定されたパス内で検索していました。たとえば、foo/bar/FooBar.java をコンパイルし、クラス FooBarHelper クラスに依存しているとします。 javac は、CLASSPATH 内でソースファイル Helper.java の検索を試みます。
    % 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
    % 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
    % javac /tmp/foo/bar/FooBar.java
Java 2 SDK でも、-sourcepath <path> オプションを含めないと、これらのツールは CLASSPATH 内でソースファイルを検索します。 -sourcepath <path> オプションを含める場合、ソースファイルは <path> 内でだけ検索され、CLASSPATH 内では検索されません。
    % setenv CLASSPATH /tmp

    # This still works with the Java 2 SDK: 
    % javac /tmp/foo/bar/FooBar.java

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