Java 2 SDK 開発ガイド (Solaris 編)

実行時の非互換性の問題

  1. JDK 1.0 および 1.1 の実行システムは、いくぶん積極的にオブジェクトをファイナライズします。すなわち、finalize メソッドを呼び出します。つまり、適格ではあるが、unfinalize されていない状態のオブジェクトは、ほぼすべてのガベージコレクションサイクルの最後にファイナライズされることがあります。これらの実行システム用に作成されたコードは、正しい動作のために、この即時 GC 駆動ファイナライズを無意識に前提としている可能性があります。これは複雑なバグやデッドロックを発生させる可能性があります。

    Java 2 SDK Solaris 版では、ガベージコレクタによって直接にファイナライズが行われることはありません。その代わりに優先度の高いスレッドによってオブジェクトがファイナライズされます。このため、使用中のプログラムでは、オブジェクトが適格になってからファイナライズされるまでの時間が、以前のバージョンの実行システムより長くなることがあります。

    Java 2 SDK Solaris 版の実行システムでは、JLS のファイナライズの定義が正しく実現されているため、厳密に言うと、この違いが互換性の問題になることはありません。ただし、即時ファイナライズに依存している場合、この変更によってプログラムが誤作動することがあります。多くのプログラムは、finalize メソッドではなく、参照オブジェクトを使用することによって修正することができます (参照オブジェクトは、java.lang.ref.Reference クラスとそのサブクラスで実装する)。 また、あまり望ましい回避策ではありませんが、定期的に System.runFinalization メソッドを呼び出す方法もあります。

  2. Java 2 SDK Solaris 版より前のバージョンの Virtual Machine は、JLS に従えば拒否されるべき一部のクラスファイルを受け付けます。一般的に、そうしたクラスファイルには、次の問題が少なくとも 1 つ存在します。

    1. ファイルの末尾に余分なバイトがある

    2. ファイルに、英字以外の文字で始まるメソッドまたはフィールド名が含まれている

    3. クラスが別のクラスの private メンバへのアクセスを試みる

    4. ファイルに、不正な定数プールインデックス、不正な UTF-8 文字列などの書式エラーが含まれている

    Java 2 SDK Solaris 版 VM は、これらのすべてに関してさらに厳密になるように、仕様により忠実に実装されています。

    Java 2 SDK Solaris 版の RC2 リリースになるまで、デフォルトではこの厳密な検査になっていました。しかし、最終的な製品テストでは、こうした厳密な検査のために、既存の多数の Java アプリケーションが実行できないことが明らかになっています。具体的には、理解しにくいコードでは a および b の問題が頻繁に発生し、以前のコンパイラで生成された内部クラスのコードは c の問題を抱えています。Java 2 SDK Solaris 版の最終版では、開発者や一般ユーザができる限り少ない労力で Java 2 SDK Solaris 版にアップグレードできるよう、これらの検査の一部が緩和されています。

    Java 2 SDK Solaris 版の -Xfuture オプションは、クラスファイルのできる限り厳密な形式検査、アクセス検査、検査ポリシーを有効にします。開発者は、できる限り速やかに新たに始まる開発プロジェクトでこのオプションを使用してください。これにより、新しい Java アプレットおよびアプリケーションが、再びデフォルトになる厳密な動作に移行できるようになります。

    Java Plug-in は、あたかも -Xfuture が設定されているかのようにつねにクラスファイルの厳密な検査を行います。appletviewer は -Xfuture フラグを無視し、厳密さでは劣るデフォルトの一群の検査を行います。

  3. Java 2 SDK Solaris 版では、abstract メソッドまたは interface メソッドが実装されていないと、実行時にそのメソッドが呼び出されたときに AbstractMethodError が発生します。以前のバージョンでは、このエラーはリンク時に発生していました。

  4. Java 2 SDK Solaris 版より前では CLASSPATH にコードを書き込むと、特権レベルが高くなります。このために、たとえば、Java 2 SDK Solaris 版より前の VM では、信頼されているクラスファイルの検査が行われないことがあります。検査は、インストールされているセキュリティマネージャに依存します。たとえば、CLASSPATH に指定されたクラスに次のメッセージがあり、アプレットによって呼び出された場合、そのメソッドは user.name プロパティを読み取ることができました。


    String getUser() {
    	return System.getProperty("user.name");
    }

    Java 2 SDK Solaris 版では、この種のコードは、次の例に示すように、Privileged を呼び出す必要があります。


    String getUser(){
    		return(String)
    		java.security.AccessController.doPrivileged
    																	(new PrivilegedAction(){
    			public Object run() {
    				return System.getProperty("username");
    			}
    		})
    }
    • Java 2 SDK Solaris 版のセキュリティモデルでは、資源アクセス方法が変更されています。セキュリティマネージャが有効な場合、資源は URL ポリシーファイルによって付与された適切なセキュリティアクセス権を持つ URL に存在する必要があります。デフォルトのポリシーファイル (java.policy) は、lib/ext ディレクトリ (拡張機能が格納されているディレクトリ) に存在する資源にすべてのセキュリティアクセス権を付与します。デフォルトのポリシーファイルは、/lib/security/java.policy にあります。

      さらに、システム資源にアクセスするための呼び出し (たとえば、ClassLoader.getResource による) は、AccessController.doPrivileged の呼び出しで囲む必要があります。doPrivileged 文を使用せずにシステム資源にアクセスしようとすると失敗します。これは、ポリシーファイルによってシステム資源にセキュリティアクセス権が付与されていた場合でも同様です。

  5. JDK 1.1.6 より前では、デフォルトの ISO 8859-1 文字エンコーディングの名前は 8859_1 でした。JDK 1.1.6 では、この名前は ISO8859_1 に変更されています。API において引数としてメソッドに渡した場合、古い名前の 8859_1 は機能しますが、font.properties ファイルで使用された場合は、機能しません。

  6. java.util.zip パッケージの次の各クラスには、バッファサイズを指定する int パラメータを受け付けるコンストラクタが追加されています。

    • DeflaterOutputStream

    • InflaterInputStream

    • GZIPInputStream

    • GZIPOutputStream

    バッファサイズの入力パラメータ値が 0 以下の場合、Java 2 SDK Solaris 版では、IllegalArgumentException がスローされます。JDK 1.1 プラットフォームでは、サイズパラメータが 0 以下であっても、これらのコンストラクタは IllegalArgumentException をスローしません。

  7. Java 2 SDK Solaris 版の VM は、クラスファイル形式が不正なクラスファイルのロードが試みられると、java.lang.ClassFormatError をスローします。また、サポートされているメジャーまたはマイナーバージョンではないクラスファイルのロードが試みられると java.lang.UnsupportedClassVersionError をスローします。以前のバージョンの Virtual Machine は、クラスファイルにこうした問題があると、java.lang.NoClassDefFoundError をスローしていました。

  8. Java 2 SDK Solaris 版では、アプリケーションクラスは実際の ClassLoader インスタンスによってロードされます。したがって、アプリケーションクラスは、インストールされた拡張機能を使用することができ、アプリケーションのクラスパスとブートストラップのクラスパスを分離できます。アプリケーションのクラスパスはユーザが指定しますが、ブートストラップのクラスパスは一定であり、ユーザが修正すべきものではありません。必要な場合は、-Xbootclasspath オプションを使ってブートストラップのクラスパスを無効にできます。

    しかし、このことは、Java 2 SDK Solaris 版では、アプリケーションクラスがデフォルトですべてのアクセス権を持つことはなくなることを意味します。この代わりに、アプリケーションクラスには、システムの構成されたセキュリティポリシーに基づいてアクセス権が与えられます。そのため、1.0/1.1 の元のセキュリティモデルに基づいて作成された独自のセキュリティコードを含むアプリケーションは例外をスローし、Java 2 SDK Solaris 版で起動しないことがあります。この問題を回避するには、このアプリケーションを oldjava アプリケーション起動ツールを使って実行します。この説明は、java アプリケーション起動ツールのリファレンスページに記載されています。oldjava ユーティリティの詳しい使用方法については、第 4 章「Java 2 SDK と JDK 1.1 のコマンド行の相違点」を参照してください。

    新しい拡張機能機構と、クラスのロードに対するその効果について、詳しくは http://java.sun.com/products/jdk/1.2/ja/docs/ja/guide/extensions/spec.html の「拡張機能機構の仕様」を参照してください。このドキュメントでは、新しいクラスローダ委託モデルとクラスローダの API の変更に関係する情報も提供します。

    Java 2 SDK Solaris 版のセキュリティモデルについては、http://java.sun.com/products/jdk/1.2/ja/docs/ja/guide/security/index.html の JDK セキュリティドキュメントを参照してください。

  9. Java 2 SDK Solaris 版では、パッケージ java.io の一部のクラスに、入力パラメータが無効でないかどうかを検査するコンストラクタが追加されています。このような検査は、このプラットフォームの以前のバージョンでは行われていませんでした。

    • out パラメータが null である場合、 PrintStream(OutputStream out) および PrintStream(OutputStream out, boolean autoFlush) コンストラクタは NullPointerException をスローします。

    • in パラメータが null である場合、InputStreamReader(InputStream in) および InputStreamReader(InputSteam in、String enc) コンストラクタは NullPointerException をスローします。

    • Java 2 SDK Solaris 版では、lock パラメータが null である場合、Reader(Object lock) および Writer(Object lock) コンストラクタは NullPointerException をスローします。

  10. JDK 1.1 ソフトウェアでは、Thread.stop は、Object.wait または Thread.sleep でブロックされたスレッドの実行を中断することができます。ただし、Solaris 8 オペレーティング環境でネイティブスレッドを持つ Java 2 SDK Solaris 版では、Thread.stop がブロックされたスレッドの実行を中断することはできません。ただし、他のオペレーティングシステムや Solaris 2.6 オペレーティングプラットフォームでは、Java 2 SDK Solaris 版は Thread.stop に関して JDK 1.1 リリースと同じ動作をします。

  11. Java 2 SDK Solaris 版では、クラスローディング機構が改定されています。新しいクラスローダでは、jar ファイルのパッケージに属するいずれかのクラスファイルが署名されている場合は、同じパッケージに属するすべてのクラスファイルが同じ署名者によって署名されていなければなりません。したがって、パッケージのあるクラスが署名されているのに、他のクラスが署名されていないか、または別の署名者によって署名されている jar ファイルは使用できなくなります。jar ファイルには署名されていないパッケージが含まれていてもかまいませんが、パッケージのいずれかのクラスが署名されている場合は、そのパッケージのすべてのクラスファイルが同じ署名者によって署名されていなければなりません。既存の jar ファイルがこの規則に従っていない場合は、これを Java 2 SDK Solaris 版または Runtime Environment で使用することはできません。

  12. ネイティブ構成要素のフォアグラウンドとバックグラウンドの色は、SetForeground()SetBackground() メソッドを使って明示的に設定できます。これらの色を明示的に指定しないと、デフォルトの色は次のように設定されます。

    • Java 2 プラットフォームでは、ネイティブ構成要素のデフォルト色は、使用中のオペレーティングシステムによって定義されている色になります。

    • Java 2 SDK Solaris 版より前のバージョンでは、デフォルト色は Java プラットフォーム自体によって事前に定義されていました。

デフォルト色に依存するコードが JDK 1.1 でコンパイルされている場合には、これを Java 2 SDK Solaris 版で実行すると、構成要素の色がデフォルト色とは異なった色になり、ときには不適切な色になることがあります。たとえば、JDK 1.1 のコードで構成要素ラベルのフォアグラウンド色を白に明示的に設定し、デフォルトのバックグラウンド色を使用するとします。これを Java 2 SDK Solaris 版で実行すると、オペレーティングシステムのデフォルトのバックグラウンド色が白の場合、ラベルは見えません。