ClassFormatError
この問題は、古い JDK 1.0.2 または 1.1 コンパイラによって生成されたバイトコードが原因で発生します。このバイトコードが Java VM 仕様に準拠していないからです。 最近の J2SE リリースのべリファイアは不正なクラスフォーマットに関して非常に厳しくなっているため、こうした不正なクラスファイルがロードされたら VM によって ClassFormatError
がスローされます。
不正なクラスファイル形式をもついくつかのアプレットを Java 2 で実行できるようにするために、Java Plug-in には、不正なクラスファイルを正しいものに変換するバイトコード変換プログラムが取り入れられています。 現時点では、以下の ClassFormatError
による不正なクラスファイルだけが変換されます。
残念ながら以下の ClassFormatError
は、バイトコード変換プログラムでは修正されません。したがって、これらの既知の問題を抱えるクラスファイルはどれも Java 2 では実行されません。
sun.audio
によるセキュリティ例外JDK 1.1 のアプレットでは sun.audio
パッケージにアクセスできました。 しかし、Java 2 ではアプレットサンドボックスが閉じられたため、sun.audio
パッケージのクラスライブラリにアクセスしようとしたアプレットは SecurityException
になります。
アプレットの互換性を最大限にするため、Java Plug-in ではアプレットサンドボックスが開けられ、アプレットが再び sun.audio
パッケージにアクセスできるようになりました。
AppletContext.getAudioClip()
および AppletContext.getImage()
のリソースが検索できない Microsoft による実装と Sun による実装では、AppletContext.getImage()
および AppletContext.getAudioClip()
のリソースルックアップシーケンスが異なっています。
Microsoft VM では、リソースは以下の順序で検索されます。
archive
または cabbase
パラメータで指定されたアーカイブ codebase
の URL Sun による実装では、リソースは codebase
の URL に基づいて検索されます。
この結果、Microsoft VM のリソースルックアップシーケンスに依存したアプレットの中には、Java 2 ではリソースを正しくロードできないものもあります。
アプレットの互換性を最大限にするため、Java Plug-in ではリソースルックアップシーケンスが以下のように変更されました。
archive
パラメータで指定されたアーカイブ codebase
の URLClassLoader
共有ポリシーClassLoader
共有ポリシーは、Microsoft による実装と Sun による実装で異なっています。
Microsoft VM では、以下のすべてに当てはまる場合だけ ClassLoader
オブジェクトがアプレット間で共有されます。
codebase
の値が同じであるarchive
の値が同じであるcabbase
の値が同じであるSun による実装では、以下の場合だけ ClassLoader
オブジェクトがアプレット間で共有されます。
codebase
の値が同じである Microsoft VM の共有ポリシーに依存するアプレットの中には、潜在的なクラス定義の競合のために Java 2 では正しく実行されないものもあります。
アプレットの互換性を最大限にするため、Java Plug-in では ClassLoader
共有ポリシーが以下の要件に変更されました。
codebase
の値が同じであり、かつ cache_archive
の値が同じであり、かつ java_archive
の値が同じであり、かつ archive
の値が同じであるJava 2 の備えている新しいセキュリティモデルは、JDK 1.1 よりもはるかにすぐれた機能と柔軟性を提供しています。 Microsoft VM セキュリティモデルは、JDK 1.1 と独自の技術に基づいています。
この問題は解決不能であるため、Microsoft のセキュリティモデルに依存したアプレットは Java 2 では正しく実行されません。
Java 2 および JDK 1.1 におけるアプレットのパッケージ化は、.jar
ファイルを通じて実行されます。 しかし、Microsoft VM ではアプレットのパッケージ化が、.jar
ファイルおよび独自の .cab
(cabinet) ファイルを通じてサポートされています。
この問題は解決不能であるため、Microsoft の .cab
ファイル形式でパッケージ化されたアプレットは Java 2 にロードされません。
null
と長さゼロの String
)JDK 1.1 では、クラスライブラリにおける null
と長さがゼロの文字列の取り扱いに関する Java 言語仕様が緩やかでした。 API によっては null
を、長さゼロの String
として扱うものもあれば、null
そのものとして扱うものもありました。 Java 2 では Java 言語仕様が厳密になり、正確な動作を指定するようになりました。
この問題は解決不能であるため、null
を長さゼロの String
として処理する API に依存しているアプレットは、Java 2 では例外となります。
Java 2 では、アプレット署名を RSA および .jar
ファイルを通じてサポートしていますが、Microsoft ではアプレット署名を、独自の Authenticode および .cab
テクノロジを通じてサポートしています。
この問題は解決不能であるため、Microsoft の Authenticode および .cab
テクノロジに依存する署名アプレットは、java 2 では正しくロードされません。
JDK 1.1 では、AWT クラスライブラリが開発者によって、スレッドに対して安全なライブラリとして使用されていました。つまり、アプレットは複数のスレッドで AWT を通じて多くのアクションを実行し、クラスライブラリが同期化の問題を処理するものと見なしていました。 Java 2 では AWT クラスライブラリの実装が変更され、AWT イベントディスパッチスレッドによって呼び出された場合だけスレッドの安全性が保証されるようになりました。
この問題は解決不能であるため、スレッドの安全性に関する問題を配慮せずに AWT クラスライブラリを呼び出した Java 2 のアプレットは、デッドロックまたは競合状態に陥ります。
Microsoft による実装では、HTML ページの JavaScript で公開されるアプレットのメソッドとプロパティは、アプレットオブジェクトのメソッド/フィールドとまったく同じものです。 Java Plug-in では、HTML の JavaScript で公開されるアプレットのメソッドとプロパティは、JavaBeans のイントロスペクションを通じて取得されます。JavaBeans のイントロスペクションは、アプレットオブジェクトの命名規則によってメソッドとプロパティの分析を行います。 これによる影響として、アプレットのフィールドがそれぞれ異なる方法で処理されます。
この問題は Java Plug-in の今後のリリースで解決される予定です。現在のところ、Java 2 ではアプレットオブジェクトのフィールドにアクセスする JavaScript は正しく動作しません。
Microsoft による VM の実装では、J/Direct、AFC、WFC など多くの独自のクラスライブラリが提供されています。
この問題は解決不能であるため、Microsoft の独自の Java クラスライブラリに依存したアプレットは Java 2 では正しく動作しません。
Applet.getParameter()
から返される文字列内の空白文字Microsoft による実装では、文字列が Applet.getParameter()
内でアプレットに返される前に、空白文字が取り除かれます。 しかし、Sun による実装では、文字列は HTML パラメータで指定されたとおりに返されます。 この結果、JDK 1.1 アプレットの中には Java 2 で実行できないものがあります。JDK 1.1 アプレットのロジックでは、空白を想定していないためです。
アプレットの互換性を最大限にするため、Java Plug-in では Applet.getParameter()
の実装が変更され、戻り値から空白文字が取り除かれています。
java.util.Hashtable.hashCode()
における設計変更JDK 1.1 では Hashtable.hashCode()
はオブジェクト ID に基づいて実装されているので、hashCode()
が呼び出された場合、Hashtable
オブジェクトはそれぞれ一意の値を返します。 Java 2 では Hashtable.hashCode()
の実装が、Java Collection Framework の一部として値に基づくものに変更されました。 Hashtable
オブジェクトは、格納しているオブジェクトに基づいてハッシュコードの値を返します。
この変更によって、JDK 1.1 のアプレットのいくつかは、Hashtable
オブジェクトをそれ自身に追加した場合に中断してしまいます。なぜなら、この変更は Collection Framework の基本設計を乱し、StackOverflowError
が発生するからです。 同じ Hashtable
オブジェクトから一定の値を返すために、Hashtable.hashCode()
に依存しているいくつかのアプレットで、コードのロジックが破壊されてしまいます。
アプレットの互換性を最大限にするため、Hashtable.hashCode()
の実装が変更され、こうした特別なケースをチェックしてスタックのオーバーフローを回避するようになりました。
マウスイベントの追跡やその他の理由により、アプレットがそのフレームにアクセスしようとすることがあります。 Microsoft による実装と Sun による実装では、フレームとアプレットの間でコンテナ数が異なります。
Microsoft VM における特定の包含レベルにあるフレームの位置に依存する (AWT 階層コンポーネントツリー全体をナビゲートしない) アプレットは、Java 2 では失敗する可能性があります。最もよく見られる症状は、AWT ディスパッチイベントスレッドからの ClassCastException
です。
この問題は解決不能であるため、この問題の影響下にあるアプレットは Java 2 では正しく実行されません。
MAYSCRIPT
Netscape Navigator と Java Plug-in では、JavaScript にアクセスするアプレットはアプレットタグで MAYSCRIPT
パラメータを指定する必要があります。 しかし Microsoft による実装ではこのパラメータが重視されないため、アプレットはあらゆる条件下で JavaScript にアクセスすることができます。 インターネット上のアプレットのほとんどは、Microsoft VM をターゲットにしているため、MAYSCRIPT
が指定されていません。
アプレットの互換性を最大限にするため、Java Plug-in から MAYSCRIPT
のチェックが削除されました。
Microsoft と Sun による実装では、HTTP 接続が要求されたときに、異なる HTTP ユーザエージェントの文字列がサーバに渡されます。 多くの Web サイトが Sun ではなく Microsoft VM をターゲットにしているため、こうした Web サイトでは Sun の HTTP ユーザエージェントを認識せず、失敗が起こります。
この結果、Java Plug-in で使用される HTTP ユーザエージェントがブラウザで使用されるものと同じものに変更されました。これで、Web サーバのほとんどが、Java Plug-in で実行するアプレットによって作成された要求を認識するようになります。
Microsoft と Sun による実装では、アプレットの起動時と停止時に発生するイベントは完全に同じではありません。 たとえば、アプレットのロジックが Applet.start()
または Applet.stop()
の呼び出し時に表示されるアプレットに依存することは、Microsoft による実装には当てはまりますが、Sun による実装には当てはまりません。
Microsoft VM においてアプレットが起動または停止するときの特定のイベントに依存しているアプレットは、Java 2 では正しく機能しません。最もよく見られる症状は、AWT ディスパッチイベントスレッドからの NullPointerException
です。
この問題は解決不能です。
Java 2 の Java クラスライブラリでは多くの変更が行われました。API の中には実装において明確になったもの、切り下げられたもの、置き換えられたものがあります。 以下は、Microsoft の VM で実行されるアプレットが Java 2 では失敗することの原因となっているものです。
java.awt.Graphics.drawString()
Microsoft VM では、
drawString()
はnull
を空の文字列として扱います。 Java 2 では、drawString()
はnull
をそのものとして扱うため、NullPointerException
がスローされます。
java.awt.Graphics.drawImage()
Microsoft VM では、
drawImage()
はnull
イメージを無視します。 Java 2 では、drawImage()
はnull
をそのものとして扱うため、NullPointerException
がスローされます。
java.awt.Color
コンストラクタMicrosoft VM では、
Color
コンストラクタに境界値を上回ったり下回ったりする値が渡された場合、コンソールで警告メッセージが出力されますが、値は最大値または最小値に自動的にリセットされます。 Java 2 ではColor
コンストラクタが不正な値をチェックし、IllegalArgumentException
をスローします。
Thread.stop()
、Thread.suspend()
、Thread.resume()
Microsoft VM では、デッドスレッドの停止、中断、再開に関する呼び出しは無視されます。 Java 2 では、デッドスレッド上でこうしたメソッドを呼び出すと
AccessControlException
が発生します。これらの問題はすべて解決可能ですが、まだ解決されていません。 現時点では、これらの問題の影響下にあるアプレットは例外となり、Java 2 では正しく実行されません。