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

API の非互換性の問題

  1. Java 2 SDK Solaris 版では、ActiveEvent クラスは java.awt パッケージにあります。以前は、java.awt.peer にありました。

  2. Swing および Accessibility 関連のパッケージは、com.sun.java.* 名前空間から javax.* 名前空間に移動しました。これらのパッケージの新しい名前は以下のとおりです。

    • javax.swing

    • javax.swing.border

    • javax.swing.colorchooser

    • javax.swing.event

    • javax.swing.filechooser

    • javax.swing.plaf

    • javax.swing.plaf.basic

    • javax.swing.plaf.metal

    • javax.swing.plaf.multi

    • javax.swing.table

    • javax.swing.text

    • javax.swing.text.html

    • javax.swing.tree

    • javax.swing.undo

    • javax.accessibility

      これらの Swing 1.0 のパッケージに対して古い com.sun.java.swing* 形式のパッケージ名を使用しているアプリケーションは、Java 2 SDK Solaris 版プラットフォームでは動作しません。新しい java.swing 形式のパッケージ名を使用するようにアプリケーションを更新してください。以上の変換に必要な PackageRenamer ツールは http://java.sun.com/products/jfc/PackageRenamer で入手できます。


      注 -

      com.sun.java.swing.plaf.windows および com.sun.java.plaf.motif パッケージの名前は変更されていません。


      古いパッケージ名を使用しているアプリケーションを強制的に Java 2 SDK Solaris 版プラットフォームで動作するようにすることができます。このためには、起動クラスパスの先頭に Swing 1.0 jar ファイルのパスを設定します。


      java -Xbootclasspath:<path to 1.0 swingall.jar>:<path to Java 2 SDK
      rt.jar> ...

      注 -

      Java 2 SDK Solaris 版の Swing パッケージでは、Java 2 SDK Solaris 版のセキュリティ対応するための変更が加えられている点に注意してください。このため、セキュリティマネージャが存在する環境で、この方法を使用して、Java 2 SDK Solaris 版で Swing 1.0 クラス (すなわち、ブラウザ内のアプレットとして) を実行した場合は、プログラムが正しく動作しないことがあります。


  3. Java 2 SDK Solaris 版では、java.awt.datransfer クラスの次のフィールドが final になっています (stringFlavorplainTextFlavor フィールド)。


    public static final DataFlavor stringFlavor
    public static final DataFlavor plainTextFlavor
  4. Java 2 SDK Solaris 版には、java.util.List インタフェースが含まれています。このため、既存のソースコードを変更しないと、java.awt.Listjava.util.List の間で名前空間の競合が発生する可能性があります。

    次の例に示すように、Java 2 SDK Solaris 版でワイルドカード付きの import 文をまとめて使用し、コードに無修飾名の List が含まれていると、コンパイルエラーになります。


    import java.awt.*;
    import java.util.*;

    この問題を回避するには、次のような import 文を追加して、ファイル全体で衝突を解決するか、


    import java.awt.List;

    あるいはクラス名を使用するたびに適切なパッケージでクラス名を完全修飾します。

  5. Java 2 SDK Solaris 版では、java.awt.event.KeyEvent クラスの CHAR_UNDEFINED フィールドの値は 0x0ffff です。JDK 1.1 リリースでは、このフィールドの値は 0x0 でした。この変更は、0 が有効な Unicode 文字で、CHAR_UNDEFINED の定義に使用できないためです。

  6. Java 2 SDK Solaris 版では、java.io.StringReader.ready メソッドのシグニチャーが変更され、StringReader が閉じている場合に IOException をスローできるようになっています。StringReader クラスは、abstract クラスの拡張対象の java.io.Reader に記述されている一般規約を正しく実装しています。

  7. Java 2 SDK Solaris 版の Integer.decode() および Short.decode() に関する仕様には、負数の正しい表現が明記されています。負数はかならず負符号 (-) で始めます。16 進数または 8 進数の場合は、基数指示子 (0x、#、0) は負符号の後ろに付けます。

    Java 2 SDK Solaris 版では、基数指示子の前または後ろに負符号を付けるように明確に規定していませんでした。実装状態では、基数指示子は負符号の前につくと想定されていました。

    たとえば、Java 2 SDK Solaris 版で -0x5 をデコードすると負の 5 (-5) が返され、0x-5 をデコードすると NumberFormatException がスローされます。JDK 1.1 では、結果は逆になり、-0x5 では NumberFormatException がスローされ、0x-5 では負の 5 (-5) が返されます。

    JDK 1.1 で使用されていたデコード規則は一般的なものではなく、文書化もされていませんでしたが、プログラムの中にはこの動作に依存しているものがあります。

  8. Java 2 SDK Solaris 版では、クラス java.util.Vectorjava.util.Hashtable が改良され、関連するインタフェースが新しい Collections Framework (それぞれ java.util.List と java.util.Map) に実装されました。その結果、equals メソッドと hashCode メソッドのセマンティクスが変更され、これらのメソッドでは List.equalsMap.equals に規定される一般的な規約に従って、参照の等価性の代わりに値の等価性が提供されます。

    これにより互換性の問題がいくつか生じます。

    • 「自己参照」 (Vector または Hashtable をそれ自身に挿入する) は、状況によってはスタックオーバーフローを引き起こすことがあります。

      1. Hashtable をキーとしてそれ自身に挿入すると Hashtable が壊されるため、その後の操作によってスタックオーバーフローが起ることがあります。(Hashtable のキーとして使われるオブジェクトを変更することは今までも許されていませんでした。オブジェクトを Hashtable に挿入すると等価の比較に影響があるため、これは変更とみなされます。)

      2. Hashtable にそれ自身が値 (または要素ともいう) として含まれていると、equals と hashCode が規約によって定義されていないため、hashCode メソッドや equals メソッドをこのような「自己参照的な」Hashtable に対して呼び出したときに、スタックオーバーフローになることがあります。

      3. Vector にそれ自身が要素として含まれていると、equals と hashCode が規約によって定義されていないため、スタックオーバーフローが起ることがあります。

    • equals と hashCodeVectorHashtable の内容に依存するようになったため、それらは同じコレクションに対する他の操作に対し同期化されます。Java 2 SDK Solaris 版より前は、これらのメソッドは同期化されませんでした。したがって、equals や hashCode が同期化されないことをクライアントが前提にしていると、この新しい同期化によって (プロセスの) 活動性の問題が生ずることがあります。

    • VectorHashtable に対する equals の「参照の等価性」に明示的に依存しているクライアントは、正しく動作しません。たとえば、プログラムに保持されている Hashtable のキーがすべて何らかのシステムの Vector (または Hashtable) だとします。今まではそれぞれの Vector (または Hashtable) は内容と関係なく個別のキーでした。しかし、現在は 2 つの Vector (または Hashtable) の内容が同じであれば、それらは同じものとみなされます。さらに、Hashtable 内でキーとして使用されている VectorHashtable を変更することはできなくなります。

    • equals と hashCodeVectorhashCode の内容全体を調べるため、大きなコレクションでは、従来よりも時間がかかることがあります。

  9. 新しいバージョンの File クラスは、当初意図されていた動作と現在の一般的な用途の両方に対応しています。しかし、動作のわずかな違いによって、一部プログラムの実行が失敗することがあります。

    • 新しいバージョンの File クラスはまた、冗長な区切り文字 (パス名文字列の最後にある区切り文字など) を削除します。このため new File ("foo//bar/").getPath() 式の評価は、UNIX システムでは foo/bar になります。

  10. Java 2 SDK Solaris 版では、java.lang.ThreadcheckAccess メソッドがファイナルです。JDK 1.1 プラットフォームでは、 checkAccess はファイナルではありませんでした (バグ ID 4151102)。

  11. Java 2 SDK Solaris 版では、配列を表すクラスで呼び出されたとき、class java.lang.ClassgetInterfaces メソッドは Cloneable および Serializable クラスオブジェクトを含む配列を返します。JDK 1.1 では、getInterfaces は空の配列を返していました。

  12. JDK 1.1 のときと異なり、Java 2 SDK Solaris 版では、abstract クラスの java.text.BreakIteratorjava.text.SimpleTextBoundaryjava.text.Collator (Collator のサブクラスの java.text.RuleBasedCollator も含めて) は、Serializable インタフェースを実装しません (バグ ID 4152965)。

  13. Java 2 SDK Solaris 版では、PersonalJavaTM プラットフォーム用の Input Method Framework の 1 機能として、java.awt.Graphics クラスに abstract メソッドの drawString(AttributedCharacterIterator,int,int) が追加されています。普通、1.1 プラットフォーム用に作成されたアプリケーションに Graphics のサブクラスが存在することはめったにありません。しかし、1.2 プラットフォームでも使用するには、そうしたサブクラスでこの新しい abstract メソッドを実装する必要があります (バグ ID 4128205)。

  14. JDK 1.1 に実装されている String ハッシュ関数は、初版の JLS に規定されている関数と異なっていました。実際には、規定されている関数は、入力文字列の外部の文字を扱うという点において実装不可能です。また、実装されている関数は、URL などの一部文字列クラスでうまく動作しませんでした。

    実装を仕様に合わせて、動作上の問題を解決するために、仕様と実装の両方が修正されています。Java 2 SDK Solaris 版の String hash() 関数は、次のように規定されています。


    s[0] * 31^(n-1) + s[1] * 31^(n-2) + ... + s[n-1]

    s[i] は、文字列 si 番目の文字です。

    通常、ほとんどのアプリケーションはこの変更の影響を受けません。実際の String ハッシュ値に依存する固定データがある場合、理論上、アプリケーションが影響を受ける可能性はありますが、Hashtable の直列化表現が、Hashtable に含まれるキーの実際のハッシュ値に依存することはありません。つまり、固定データの格納に関して直列化に依存するアプリケーションが影響を受けることはありません (バグ ID 4045622)。

  15. Java 2 SDK Solaris 版は、NMI (Native Method Interface) をサポートしていません。

    JDK 1.0 がサポートする NMI を使用して作成した非 JNI ネイティブメソッドがあるか、JNI Invocation Interface を使用して実行環境を組み込むようにしている場合、Java 2 SDK Solaris 版で使用するには、ネイティブライブラリを再リンクする必要があります。Solaris 環境では、リンクコマンド行の -ljava-1jvm に置き換える必要があります。また、JNI に合わせて書き直す必要があります。


    注 -

    この変更は、JNI プログラミングにおけるネイティブメソッドの実装には影響ありません。


    Java 2 SDK Solaris 版では、Sun は JNI だけをサポートします。JNI は、ネイティブライブラリと Java プログラミング言語を連携させる標準の手段です。JNI は、VM から独立したネイティブコードを作成することを可能にします。メソッドで NMI を使用している場合は、第 3 章「Java Native Interface (JNI)」のネイティブメソッドの JNI への移行に関する説明を参照してください。

  16. Thread.suspend() メソッドを使用すると、デッドロック状態になることがあります。このメソッドは本質的に安全ではないため、その使用は推奨されていません。これは、Thread.stop()Thread.resume() などの、その他の非同期の thread メソッドについても同じです (バグ ID 4203325)。

    Thread.suspend() は安全ではありません。これは、たとえば、メソッドの同期中に、Thread.suspend() がスレッドの実行を中断させることがあるためです。この中断によって、他のスレッドがロックアウトされる可能性があり、その場合、デッドロック状態になることがあります (詳細については、http://java.sun.com/products/jdk/1.2/ja/docs/ja/guide/misc/threadPrimitiveDeprecation.html のリファレンスプラットフォームのマニュアルを参照してください)。

  17. JDK 1.1 では、Thread.stop は、Object.wait または Thread.sleep でブロックされたスレッドの実行を中断することができます。ただし、ネイティブスレッドを持つ Java 2 SDK Solaris 版では、Thread.stop がブロックされたスレッドの実行を中断することはできません。ただし、他のオペレーティングシステムまたはグリーン (非ネイティブ) スレッドを持つ Solaris 2.6 では、Java 2 SDK Solaris 版は Thread.stop に関して JDK 1.1 リリースと同じ動作をします。

  18. ここでは、java.sql パッケージにインタフェースを実装する開発者 (主として JDBC ドライバを実装する開発者) に関係する互換性の問題を説明します。Java 2 SDK Solaris 版では、次のインタフェースに新しいメソッドが追加されています。

    • java.sql.Connection

    • java.sql.DatabaseMetaData

    • java.sql.ResultSetMetaData

    • java.sql.ResultSet

    • java.sql.CallableStatement

    • java.sql.PreparedStatement

    • java.sql.Statement

      これらインタフェースの JDK 1.1 版を実装するソースコードは、Java 2 SDK Solaris 版では正しくコンパイルされません。正しく動作するには、新しいメソッドを実装するように変更する必要があります。

      また、Java 2 SDK Solaris 版の次のインタフェースは新しい型をサポートします。

    • java.sql.ResultSet

    • java.sql.CallableStatement

    • java.sql.PreparedStatement

      これらのインタフェースを実装するソースコードや Java 2 SDK Solaris 版で正しくコンパイルされたコードは、JDK 1.1 では新しい型が存在しないため、正しくコンパイルされません。

  19. public フィールド serialVersionUID が Java 2 SDK Solaris 版 Standard Edition v1.2 で java.io.Serializable インタフェースに導入されています。このフィールドはこのインタフェースに導入すべきではありませんでした。この意味は指定されていませんし、このフィールドは java.io.Serializable の仕様に反するものです。

    java.io.Serializable の API 仕様では次のように記述されています。

    直列化インタフェースにはメソッドもフィールドもありません。

    さらに、直列化仕様によると、クラスの直列バージョン UID を取得するには ObjectStreamClass.lookup(className).getSerialVersionUID() メソッドを使用する必要がありました。しかし、存在するかどうか不明なフィールドを使ってクラスの直列バージョン UID を取得しようとすることは意味がありません。

    直列バージョン UID は計算されることもあれば、クラスに明示的に定義されることもありますが、スーパークラスやインタフェースから継承されることはありません。インタフェースのインスタンスを直接生成することはできないため、直列化システムにとってインタフェースの serialVersionUID フィールドは役に立ちません。実際、直列化システムがこのフィールドを使用することはありません。

    このような理由から Java 2 SDK Solaris 版のバージョン 1.2.2 では、public serialVersionUID フィールドは除去されています。この変更が既存のアプリケーションに影響を与えることはないはずです。