初期の難読化ツールの中には、仮想マシンの仕様で規定されているクラスファイルの形式に違反するクラスファイルを生成するものがありました。そのような不適切な形式のクラスファイルは、旧バージョンの Java 仮想マシンでは動作する場合もありますが、JDK の仮想マシンでは動作しません。この問題を回避するには、適切な形式のクラスファイルを生成する新しい難読化ツールで、クラスファイルを生成し直してください。
ソースレベルの下位互換性はサポートされていません。新しい言語機能または Java 2 プラットフォーム API を使っているソースファイルは、旧バージョンの Java プラットフォームでは使用できません。
J2SE 5.0 には、Java 2 プラットフォームの旧バージョンとの高い互換性があります。このため、既存のプログラムの多くは J2SE 5.0 でもそのまま実行できます。ただし、非常にまれなケースですが、JRE と JDK のソースとバイナリの互換性が得られなくなる場合もあります。ここでは補足として、このような特例について説明します。
-
java.net.Proxy -
java.net.Proxy クラスがバージョン 5.0 に追加され、2 つのクラスの名前が Proxy になりました。
-
java.lang.reflect.Proxy
-
java.net.Proxy
java.net.Proxy を導入すると、コンパイルユニットに以下のオンデマンドタイプインポート宣言が含まれる場合に、既存のコードでソースレベルの非互換性が生じます。
この場合は、参照があいまいなためにコンパイル時エラーが発生します。
Proxy クラスに対するあいまいな参照は、3 つめの import 文を追加することによって、java.lang.reflect.Proxy で解決できます。
import java.lang.reflect.Proxy;
この import 文を正しい場所に置くと、ソースコードは前のバージョンと同じ動作でコンパイルを行います。
-
総称化 ー 総称化 は既存のクラスやメソッドに、そのメソッドの仕様に矛盾しない方法で汎用型のパラメータや引数を追加する処理です。JSR 14 は多くのコアライブラリの総称化、特にコレクションクラスや Class クラスを明確にしました。5.0 Beta 2 リリースでは、可能な限りコアの総称化の効果が残りのプラットフォームに伝えられます。
総称化されたクラス、コンストラクタ、メソッドおよびフィールドを使用するほとんどのソースコードは 5.0 で引き続きコンパイルを行いますが、行わないものもあります。総称化の変更によってコンパイルに失敗する場合、最も簡単な回避方法は javac のコマンド行で -source 1.4 を指定することです。
この項目の詳細は近日中に更新されます。総称およびコアの総称化については
JSR 14 と generics tutorial (PDF) を参照してください。
-
仮想マシン
− 従来、Solaris/SPARC の デフォルト仮想マシン (VM) はクライアント VM でした。しかし、多くの Solaris/SPARC マシンがサーバとして使用され、パフォーマンスの点ではサーバ VM の方が適切です。したがって、5.0 では、デフォルトでサーバクラスの Solaris/SPARC マシンはサーバ VM を実行します。一般に、サーバ VM のスループットはクライアント VM よりはるかに高いですが、起動時間はやや長くなります。「サーバクラスのマシン」とは、現時点では、2 つ以上のプロセッサと 2G バイト 以上のメモリを搭載しているマシンとして定義されています。
詳細な情報については、「サーバクラスマシンの検出」および「ガベージコレクションのエルゴノミクス」を参照してください。
-
仮想マシン
− 5.0 で導入されたクラス共有機能を反映するために、java.vm.info プロパティ (「java -version」によって表示されるテキストに反映されます) が共有モードを指定するようになりました。java.vm.info プロパティ値または「java -version」の出力の終わりまですべてを解析するコードがあれば、変更する必要があるかもしれません。
詳細な情報については、バグ 4964160 および「クラスデータの共有」を参照してください。
-
仮想マシン - これまで、クラスリテラル (Foo.class など) を評価するとクラスが初期化されました。5.0 では初期化されません。前の動作に依存するコードは書き直す必要があります。
クラスを強制的に初期化するには次のコードを使用します。
//... Foo.class ... //OLD CODE
... forceInit(Foo.class) ... //NEW CODE
/**
* Forces the initialization of the class pertaining to the specified
* <tt>Class</tt> object. This method does nothing if the class is already
* initialized prior to invocation.
*
* @param klass the class for which to force initialization
* @return <tt>klass</tt>
*/
public static <T> Class<T> forceInit(Class<T> klass) {
try {
Class.forName(klass.getName(), true, klass.getClassLoader());
} catch (ClassNotFoundException e) {
throw new AssertionError(e); // Can't happen
}
return klass;
}
この新しい動作は、VM が定数プールでクラスリテラルをサポートするようになった結果です。5.0 より前のコンパイラでコンパイルしたクラスまたは -target 1.4 フラグを付けてコンパイルしたクラスには、5.0 VM で動作させたとしても古い動作が残ります。
詳細についてはJava 言語仕様のクラスおよびインタフェースの初期化 (節 12.4) を参照してください。言語仕様は変わっていませんので、クラスリテラル評価を初期化のトリガとしてリストしません。
-
クラスローダ
− 従来は、String クラス名引数をとる ClassLoader メソッドに対して非バイナリクラス名を指定することが可能でした。この予期しない動作は、クラス名の長く続いてきた仕様とは互換性がありませんでした。5.0 では、これらの ClassLoader メソッドのパラメータチェックが仕様に準拠するように修正され、バイナリ名ではないクラス名は他の認識されないクラス名と同様に扱われます。クラス名を明示的に要求または返す API (たとえば、Class.forName や Class.getName) は参照タイプとしてバイナリ名を使用するので、一般ユーザが Class を返すクラス名を作成することはないでしょう。
詳細な情報については、「Java Language Specification, Second Edition」のバイナリ名の定義を参照してください。また、バグ 4986512 の評価を参照してください。
- 直列化
− コンパイラによって生成される合成の変更はデフォルトの直列化バージョン UID に影響を与えるので、UID が明示的にオーバライドされなかった場合、直列化の非互換性が生じることがあります。
詳細な情報については、バグ 4786115 を参照してください。
-
ロギング
− 従来、java.util.logging.Level(String
name, int value, String resourceBundleName)
コンストラクタでは、null の name 引数が許されましたが、parse メソッドでは許されませんでした。5.0 では、このコンストラクタは名前が null のときには NullPointerException をスローします。このコンストラクタを使用して Level をサブクラス化し、後続の呼び出しで null の Level 名を使用すると NullPointerException が返されるので、互換性リスクが緩和されます。ただし、toString などの単純な呼び出しの場合を除きます。
詳細な情報については、バグ 4625722 を参照してください。
-
Apache
− org.apache クラスは J2SE API ではサポートされていませんでしたが、javax.xml パッケージでは使用されています。このクラスが、5.0 で com.sun.org.apache.package.internal に移動し、最近の開発者向けダウンロードバージョンのクラスでクラッシュしなくなりました。J2SE リリースの一部である org.apache クラスに依存するアプリケーションを 5.0 で動作させるには、以下のいずれかを行う必要があります。
- JAXP の一部である、サポートされるインタフェースのみを使用するように、アプリケーションをコード化する
- Apache から
org.apache.xalan クラスをダウンロードする
詳細な情報については、バグ 4740355 を参照してください。
- JAXP − J2SE 1.4 プラットフォームには JAXP 1.1 (「Crimson」) が含まれていましたが、J2SE 5.0 プラットフォームには JAXP 1.3 (「Xerces」) が含まれています。Crimson と Xerces は、同じコードベースでバージョンのみが違うわけではありません。JAXP 標準の実装が完全に異なります。両方とも JAXP 標準に準拠していますが、わずかに違いがあります。
Crimson は軽量で高速ですが、機能の面で Xerces よりはるかに劣ります (オープンソース実装が Apache にホストされています)。加えて、JAXP 標準が 1.1 から 1.3 になりました。これら 2 つの理由で互換性の問題が発生します。
詳細については、「JAXP 互換性ガイド 5.0 用」を参照してください。
- JAXP
− J2SE 1.4 プラットフォームは DOM Level 2 API をサポートしていましたが、J2SE 5.0 プラットフォームは DOM Level 3 API をサポートします。DOM Level 3 インタフェースには新しいメソッドが追加されているので、DOM Level 2 を使用している既存のアプリケーションは、新しいインタフェースではコンパイルできないことがあります。
多くの DOM Level 2 アプリケーションは、クラスパスで DOM Level 2 を DOM Level 3 で代用することで動作しますが、バージョンの違いのために NoSuchMethodException が発生することがあります。そのため、一部のアプリケーションはバイナリ互換ではなくなります。
詳細については、「JAXP 互換性ガイド 5.0 用」を参照してください。
- JAXP − J2SE 1.4 プラットフォームは SAX 2.0 API をサポートしていましたが、J2SE 5.0 プラットフォームは SAX 2.0.2 をサポートします。一般に、SAX 2.0.2 はバグフィックスリリースであり、API の変更はありません。ただし、SAX 2.0.2 リリースの一部として行われたいくつかの明確化が互換性問題の原因となる場合があります。
-
ErrorHandler、EntityResolver、ContentHandler、および DTDHandler は、アプリケーションによって null に設定できます。ただし SAX 2.0 ではこの場合、XML プロセッサは java.lang.NullPointerException をスローする必要があります。この変更は XML プロセッサに関するものです。ほとんどのパーサはデフォルト設定に戻すことで null に反応します。
-
DefaultHandler は、EntityResolver を含めて、さまざまなハンドラのデフォルトの実装クラスです。DefaultHandler での resolveEntity メソッドの実装は throws IOException やthrows SAXException として宣言されるようになりました。以前は SAXException をスローするだけでした。
-
resolveEntity メソッドによってスローされる例外のリストへの java.io.IOException の追加は、ソースに互換性のない変更です。具体的には、resolveEntity を呼び出すコードは、SAX 2.0 ではコンパイルできますが、SAX 2.0.2 ではコンパイルできません。これは、IOException と SAXException の両方を処理する必要があるためです。
詳細については、「JAXP 互換性ガイド 5.0 用」を参照してください。
-
JAXP − 以前は、Xalan がデフォルトのトランスフォーマでした。Apache コミュニティが XSLT 2.0 の開発に関して、XSLTC をデフォルトのプロセッサにすることに同意したので、5.0 から XSLTC がデフォルトのトランスフォーマになります。以下のような互換性リスクがあります。
- Xalan には XSLTC にないバグがあり、XSLTC には Xalan にないバグがあります。Xalan のバグを前提としているアプリケーションコードは失敗する可能性があります。
- XSLTC は、Xalan がサポートしているすべての拡張をサポートしているわけではありません。これらの拡張は、JAXP および XSLT 仕様の定義を超えています。この影響を受けるユーザにとっては、Apache から Xalan クラスをダウンロードするという回避策が有効です。また、今後は、XSLTC でサポートされる拡張が増えると予想されます。
詳細な情報については、「JAXP 互換性ガイド 5.0 用」を参照してください。
-
2D − 以前は、null の Image パラメータを Graphics.drawImage メソッドに渡すと、NullPointerException になりました。5.0 では違います。新しい動作では、Microsoft VM で動作していたアプリケーションは、標準 VM で動作できます。NullPointerException に依存していたアプリケーションを 5.0 で動作させるには、変更が必要です。
-
AWT − 以前は、フォーカスサイクルルートであるコンテナだけがフォーカストラバーサルポリシーを提供できました。5.0 では、どのコンテナもフォーカストラバーサルポリシーを提供できます。Container の新しい FocusTraversalPolicyProvider プロパティがそれを示します。
Java プラットフォームで提供されるフォーカストラバーサルポリシーは、フォーカストラバーサルポリシープロバイダに対応するように 5.0 で変更されました。具体的には、フォワード (バックワード) トラバーサル時にポリシーがフォーカストラバーサルポリシープロバイダを検出したときには、そのコンポーネントを提供されたフォーカスサイクルルートに属するものとして扱うのではなく、フォーカストラバーサルポリシープロバイダのフォーカストラバーサルポリシーを使用して、次 (前) のコンポーネントを取得しなければなりません。返されたコンポーネントが、フォーカストラバーサルポリシープロバイダのフォーカストラバーサルポリシーによって返された最初 (最後) のコンポーネントと同じ場合は、ポリシーを呼び出すことによって、フォーカストラバーサルポリシープロバイダの後 (前) のサイクル内の次 (前) のコンポーネントを取得できるはずです。フォーカスサイクルルートの「最初」と「最後」のコンポーネントの計算では、必要なときに (「最初」または「最後」のコンポーネント自体が Container であり、フォーカストラバーサルポリシープロバイダであるとき)、フォーカストラバーサルポリシープロバイダのフォーカストラバーサルポリシーを使用しなければなりません。
この変更はフォーカストラバーサルポリシーに新しいメソッドを必要とするものではないので、サードパーティのフォーカストラバーサルポリシーは従来どおり機能しますが、プロバイダの概念はサポートしません。
フォーカストラバーサルポリシーを作成してあり、プロバイダをサポートしたい場合は、5.0 でプラットフォームによって提供されるポリシーに加えられた変更と同様の変更を加える必要があります。
詳細な情報については、フォーカス仕様 AWT フォーカスサブシステム の 「フォーカストラバーサルポリシープロバイダ」 の節を参照してください。
-
ドラッグ&ドロップ − 以前は、X11 でサポートされるドラッグ&ドロップ (DnD) プロトコルは Motif DnD プロトコルだけでした。5.0 では、XDND プロトコルもサポートされ、Motif DnD プロトコルは Motif ライブラリに依存しないように再実装されました。新しい Motif DnD プロトコル実装と Motif ライブラリによって提供されるものとの違いによって、機能低下が発生する可能性があります。ただし、Motif ライブラリの実装にはバグがあるので、新しい実装の方が少なくとも品質が高く、よくサポートされています。
詳細な情報については、バグ 4638443 を参照してください。
- Swing − ボタンの背景色をカスタマイズするには、5.0 Java の Look & Feel テーマの Ocean で表示するようコードを変更する必要があるかもしれません。Ocean はデフォルトでボタンにグラデーションをつけます。つけたくない場合は
contentArea Filled プロパティを true に設定するか、背景を UIResource ではない Color に設定します。一般的には以下のように簡単です。
button.setBackground(Color.RED);
何らかの理由で UIResource を使用している場合は UIResource 以外の新しい Color を作成する必要があります。
button.setBackground(new Color(oldColor));
詳細な情報については、バグ 4908404 を参照してください。
- Swing -
JTree および JList では、ユーザがリードインデックスをキーボードと一緒に操作していました。たとえば、リードが JList の 4 行目にあるときに上矢印キーを押すとリードが移動して 3 行目が選択された状態になります。これらのコンポーネントではリードが「フォーカスがある」インデックスと見なされます。コンポーネントは、任意のインデックスにフォーカスインジケータを描画するかしないかを示す情報を渡します。これはインデックスがリードであるかどうかによります。
5.0 より前のバージョンでは JTable は反対のことを行っており、JTree および JList がリードを使用するのと同じ方法でアンカーインデックスを使用していました。この問題に対する修正は RFE 4759422 で要求されており、4303294 の一部として修正されました。現在 JTable は JList および JTree と一貫性を持っています。これにより、前の動作を仮定している開発者に影響が出ます。たとえば JTable で、フォーカスのあるセルとして表示されるものの情報が必要なアプリケーションがあり、それがアンカーだとします。正しい 5.0 より前のバージョンでは、あるインデックスがフォーカスのある矩形を表示しているときに、ほかのインデックスにフォーカスすることを決定します。
このバグの詳細については 4759422 および 4303294 を参照してください。
-
JVMDI - 5.0 バージョンで Java Virtual Machine Debug Interface (JVMDI) は非推奨です。JVMDI は次回のメジャーリリースで削除されます。新しい開発には JVMTI を使用してください。既存のツールは JVMTI に移動されます。
詳細については JVMTI のマニュアル を参照してください。
-
JVMPI - 5.0 バージョンで Java Virtual Machine Profiling Interface (JVMPI) は非推奨です。JVMPI は次回のメジャーリリースで削除されます。新しい開発には JVMTI を使用してください。既存のツールは JVMTI に移動されます。
詳細については JVMTI のマニュアルを参照してください。
-
インストール - 5.0 では、ディレクトリ、バンドル、パッケージ、レジストリ、および RPM の名前が変更されました。古いパス名に依存するスクリプトは更新する必要があります。新しい命名規約は次のとおりです。
| 古い名称 | 新しい名称 |
| j2se | java |
| j2re | jre |
| j2sdk | jdk |
大文字の使用についてはプラットフォーム規約に従います。その他のプラットフォーム固有の詳細は以下です。
Solaris
- JDK パッケージは以下にインストールされます。
/usr/jdk/jdk<version>
-
すべてのパッケージに使用されている接頭辞は「SUNWj3」(1.3 および 1.4 で使用) から「SUNWj5」に変更されました。
Linux
-
JRE および JDK の RPM は以下にインストールされます。
/usr/java/jre<version>
/usr/java/jdk<version>
-
RPM データベース名は、RPM 問い合わせを行うときに Name フィールドに表示される値です。この値は、完全修飾名 (jre-1.5.0-fcs など) を取得するために Version フィールドと Release フィールドに追加されます。
-
RPM データベースは、任意のパッケージで何が提供されているかを判定するために問い合わせを受けます。JRE と JDK は両方とも、新しい命名規約の一部として「jre」を提供し、下位互換のために「j2re」も提供します。JDK は「jdk」と、下位互換のために「j2sdk」も提供します。Sun は標準 EOL ポリシーに従って古い名称を提供しますが、新しいサードパーティのスクリプトや RPM は新しい規約を使用する必要があります。
UNIX
-
tarball が以下のように拡張されました。
./jre<version>
./jdk<version>
Microsoft Windows
-
JRE および JDK は以下にインストールされます。
%ProgramFiles%\Java\jre<version>
%ProgramFiles%\Java\jdk<version>
-
レジストリキーは変更されていません。引き続き「Java Runtime Environment」および「Java Development Kit」の完全名が使用されます。
詳細についてはJ2SE のネーミングおよびバージョン管理および J2SE 5.0 名称およびバージョンの変更 を参照してください。
-
JDBC - 5.0 では、Timestamp で compareTo を呼び出して java.sql.Timestamp と java.util.Date を比較すると ClassCastException になります。
たとえば、以下のコードは 1.4.2 では Timestamp と Date を比較できましたが、5.0 では例外で失敗します。
aTimeStamp.compareTo(aDate) //NO LONGER WORKS
この変更はコンパイル前のコードにも影響するため、前のリリースで実行するために使用されたコンパイル済みのコードが 5.0 で失敗するというバイナリ互換性の問題が起こります。
この問題は、将来のリリースで修正される予定です。
詳細については、バグ 5103041 を参照してください。
-
言語 -
5.0 の Java 言語に型保証された列挙型が追加されたことにより、enum はキーワードになり、識別子として使用することはできません。
回避策としては、javac コマンド行に -source 1.4 を指定します。これにより 5.0 で追加された言語機能はすべて無効になり、enum を識別子として使用しているコードをコンパイルできます。