JDK 6 Update 45 以降では、RMI プロパティー java.rmi.server.useCodebaseOnly
がデフォルトで true
に設定されています。以前のリリースでは、デフォルト値は false
でした。
このデフォルト値への変更により、RMI ベースのアプリケーションが予期せず停止することがあります。一般的な症状は、ネストされた java.lang.ClassNotFoundException
を含む java.rmi.UnmarshalException
を含んだスタックトレースです。
詳細は、「JDK 7 の機能拡張」を参照してください。
java.rmi.MarshalledObject
がジェネリックになりましたMarshalledObject
に、格納されている直列化されたオブジェクトの型を表す型パラメータが用意されました。null
でない RMIClientSocketFactory を含むリモートスタブでリモート呼び出しが行われると、そのファクトリオブジェクトまたは等価なファクトリオブジェクトは仮想マシンで永久にアクセス可能なままとなっていました。そのため、そのオブジェクト (およびそのオブジェクトを定義するクラスローダー) はガベージコレクトされませんでした。このバグが修正されました。リモートオブジェクトのエクスポートに使用されるソケットファクトリの場合にも同様のバグ (6332603) があります。sun.rmi.dgc.client.gcInterval
および sun.rmi.dgc.server.gcInterval
によって制御される) は、デフォルトで 1 分でした。デフォルトの間隔は 1 時間になり、特別な構成がなくても、アプリケーションでサイズの大きいヒープを利用しやすくなりました。JDK 5 Update 45 以降では、RMI プロパティー java.rmi.server.useCodebaseOnly
がデフォルトで true
に設定されています。以前のリリースでは、デフォルト値は false
でした。
このデフォルト値への変更により、RMI ベースのアプリケーションが予期せず停止することがあります。一般的な症状は、ネストされた java.lang.ClassNotFoundException
を含む java.rmi.UnmarshalException
を含んだスタックトレースです。
詳細は、「JDK 7 の機能拡張」を参照してください。
rmic
) を使う必要がなくなりました。以前のバージョンで実行されるクライアントをサポートする必要があるリモートオブジェクトに対しては、rmic
を使用して事前にスタブクラスを生成する必要があることに注意してください。
コンストラクタ、または java.rmi.server.UnicastRemoteObject
クラスまたは java.rmi.activation.Activatable
クラスの static メソッド exportObject
1 を使用してアプリケーションがリモートオブジェクトをエクスポートしても、そのリモートオブジェクトのクラスに対応する生成済みスタブクラスが読み込まれない場合、リモートオブジェクトのスタブは、呼び出しハンドラとして java.rmi.server.RemoteObjectInvocationHandler
付きの java.lang.reflect.Proxy
インスタンスとなります。そのクラスは、動的に作成されます。
java.rmi.server.ignoreStubClasses
システムプロパティーを "true"
に設定することで、動的に作成されたスタブクラスを既存のアプリケーションが無条件で使用するように配置できます。つまり、スタブクラスが事前に生成されていたかどうかにかかわらず使用できるということです。このプロパティーが "true"
に設定されていると、生成済みスタブクラスが使用されることはありません。
注:
rmic
で事前に生成されたスタブクラスを使う必要があります。または、クライアントが ClassNotFoundException
を入手して、リモートオブジェクトのスタブの直列化を復元します。リリース 5.0 より前のクライアントは、動的に生成されたスタブクラスのインスタンスを読み込むことができません。このようなクラスには RemoteObjectInvocationHandler
のインスタンスが含まれていますが、このリリースより前のバージョンでは利用できないからです。java.rmi.StubNotFoundException
がスローされます。動的に生成されたスタブクラスのサポートが追加されたため、生成済みのスタブクラスを持たないリモートオブジェクトをエクスポートしても、そのまま処理が続行されます。リリース 5.0 より前のバージョンをサポートするサーバーアプリケーションを配備しているユーザーは、エクスポート時にスタブクラスがなくてもエラーは報告されませんが、引き続きそのサーバーのリモートオブジェクトのクラスに対応するスタブクラスを必ず事前に生成する必要があります。代わりにこのようなエラーは、動的に生成されたスタブクラスの直列化を復元するときに、5.0 より前のリリースのクライアントに報告されます。1 static メソッド UnicastRemoteObject.exportObject(Remote)
は、java.rmi.server.RemoteStub
を返すように宣言されています。そのため、動的に生成されたスタブクラスをそれ自体のスタブとして使用するためにリモートオブジェクトをエクスポートする場合には使用できません。動的に生成されたスタブクラスのインスタンスは、java.lang.reflect.Proxy
インスタンスであり、RemoteStub
に割り当てられません。
javax.rmi.ssl.SslRMIClientSocketFactory
と javax.rmi.ssl.SslRMIServerSocketFactory
が追加されています。これらのクラスでは、Java Secure Socket Extension (JSSE) を使って、Secure Sockets Layer (SSL) プロトコルまたは Transport Layer Security (TLS) プロトコルを介して通信します。これらのソケットファクトリクラスでは、Java RMI で簡単に JSSE を使う方法が提供されるので、リモートメソッド呼び出しのための整合性、暗号化による機密性、サーバー認証、およびクライアント認証 (任意) を強化できます。Java RMI でのカスタムソケットファクトリの使い方の詳細は、「Java RMI によるカスタムソケットファクトリの使用」チュートリアルを参照してください。構成を含む JSSE の詳細は、「JSSE リファレンスガイド」を参照してください。inetd/xinetd
から rmid
または Java RMI サーバーを起動する (5.0 以降)System.inheritedChannel
メソッドにより提供される新しい機能によって、アプリケーションは、仮想マシン (VM) を起動したプロセスから継承されるチャネル (java.nio.channels.SocketChannel
または java.nio.channels.ServerSocketChannel
など) を取得することができます。この継承チャネルは、SocketChannel
の場合は単一の着信接続を行うため、ServerSocketChannel
の場合は複数の着信接続を受け入れるために使用できます。その結果、inetd
(Solaris(TM) オペレーティングシステム) または xinetd
(Linux) によって起動された Java ネットワーキングアプリケーションは、inetd
/xinetd
から継承された SocketChannel
または ServerSocketChannel
を取得できるようになりました。
この機能の追加によって、Java RMI 起動デーモン rmid
は、着信した接続要求を受け取ったときにのみ rmid
を起動できるように、inetd/xinetd
からの起動をサポートするように拡張されました。この機能をサポートするための rmid
の拡張機能についての詳細は、rmid
(Solaris オペレーティングシステム用) のツールページを参照してください。rmid
を起動するように inetd
を構成する方法についての詳細は、「rmid
を起動する inetd
の構成」チュートリアルを参照してください。
Java RMI を使用するアプリケーションは、inetd
または xinetd
から起動されるように設計することもできます。この技法を実装する方法の例については、「inetd
から起動されるサービスの設計」チュートリアルを参照してください。
rmic
の現在のデフォルトのスタブプロトコルのバージョン -v1.2
(5.0 以降)rmic
が実行されると、前のリリースの -vcompat
オプションの代わりに -v1.2
オプションが指定されているかのように実行されます。
つまり、この変更によって、デフォルトでは、rmic
はスケルトンクラスは生成せず、1.2 スタブプロトコルのバージョンだけを実装するスタブクラスを生成するようになりました。JDK 1.1 で実行されるクライアントをサポートするためにリモート実装クラスを構築する必要がある場合は、-vcompat
オプションを明示的に指定する必要があります。(さらに、上記のようにリモート実装クラスがリリース 5.0 より前のバージョンで実行されるクライアントをサポートする必要がない場合は、そのようなクラスのために rmic
を実行する必要はありません。)
これらのコマンド行オプションの詳細については、rmic
のツールドキュメント (Solaris および Linux 用、Windows 用) を参照してください。
rmic
がクラスパス内の任意のソースファイルをコンパイルすることはない (5.0 以降).java
ソースファイルを rmic
がコンパイルしようとすることがありました。リリース 5.0 では、rmic
は自ら生成したスタブ、スケルトン、またはタイクラス以外のソースファイルをコンパイルしようとすることはありません。
rmic
に渡されるリモート実装クラスは、そのクラスが依存しているすべてのクラスおよびインタフェースと同様に、rmic
が実行される前にすでに javac
で正常にコンパイルされています。既存の構築手順が、一部のアプリケーションソースファイルをコンパイルする rmic
の以前の動作に依存している場合、その構築手順を修正し、rmic
を実行する前に、必要なすべてのクラスが javac
で正しくコンパイルされるようにしてください。
この機能は、J2SE 1.4 の java.lang.Throwable の新しい「スタックトレース情報へのプログラムによるアクセス」機能によって可能になりました。これには、デフォルトの直列化形式の Throwable
のスタックトレースデータ部分の作成が含まれます。クライアント側 Java RMI ランタイム実装は、この機能と連携するために、以前のリリースのように単にクライアント側トレースで上書きするのではなく、クライアント側トレースを非整列化されたサーバー側トレースに追加します。
特定のサーバーアプリケーションでは、パフォーマンスや機密上の理由により、J2SE 1.4 での例外のデフォルトの直列化形式の一部としてリモート呼び出しにより直列化される例外がサーバー側スタックトレースデータで発生しないようにする場合があります。そのような場合は、実装に固有のシステムプロパティーである
sun.rmi.server.suppressStackTracesを「true」に設定すると、サーバー側 Java RMI ランタイム実装によって、リモートメソッドの呼び出しの結果、現在の仮想マシンからスローされたすべての例外のスタックトレースが消去されます。
RMIClassLoader
用サービスプロバイダインタフェース (1.4 以降)java.rmi.server.RMIClassLoader
の一部の static メソッドの動作は、新しいサービスプロバイダインタフェース java.rmi.server.RMIClassLoaderSpi
のインスタンスに委譲されています。特定のアプリケーションに対する Java RMI 動的クラスのロード動作を拡張するようにサービスプロバイダを構成できます。デフォルトでは、サービスプロバイダは、RMIClassLoader
の static メソッドすべての標準動作を実装しています。詳細については、RMIClassLoader
および RMIClassLoaderSpi
のクラスドキュメントを参照してください。java.rmi.server.hostname
プロパティーが動的に更新され、そのあとのエクスポートで新しいホスト名を使用するように指示できるようになりました。したがって、新しいホスト名の値は、このプロパティーが更新されたあとにエクスポートされるオブジェクトのスタブに格納されます。sun.rmi.transport.proxy.eagerHttpFallback
が追加され、Java RMI のデフォルトのソケットファクトリが HTTP トンネリングにフォールバックする際により細かく制御できるようになりました。このプロパティーは、デフォルトのソケットファクトリを構成して、最初の (直接的な) 接続試行によってスローされた SocketException が HTTP トンネリングのトリガーになるようにします。より「積極的」になったこのフォールバック戦略は、承認されていないポートへの接続試行を無視するのではなく、拒否するファイアウォールに対処する場合に役に立つ場合があります。java.rmi.Naming.list
メソッドは返される名前にスキーマを付加することはない (1.4.1 以降)Naming.list
メソッドは、返された文字列の配列に含まれる名前にスキーマ rmi:
を付加していました。現在の NNaming.list
の実装はその仕様に合致しており、URL 形式の名前の配列を返しますが、スキームコンポーネントは含まれません。java.rmi.activation.ActivationGroupDesc
(1.3 以降)getClassName
メソッドが、システムのデフォルトグループ実装を示す null
を返すことが可能になりました。これまでは、記述子の構築時にデフォルトのグループ実装が選択された場合、getClassName
メソッドは内部の実装クラスの名前を返していました。
この変更に対応するために、仮想マシン 1.3 で稼働するアプリケーションが新たな起動可能オブジェクトを ActivationSystem
に登録する場合、rmid
も 1.3 を実行できるようにアップグレードする必要があります。これは、1.3 より前の rmid
では新たに登録された起動可能オブジェクトを起動できないためです。
rmic
(1.3 以降)rmic
(Solaris および Linux 用、Windows 用) では、スタブのデフォルトの生成先ディレクトリが、パッケージ名の付いた、現在の作業ディレクトリのサブディレクトリになりました。「-d
」オプションを指定しない場合は、現在の作業ディレクトリ「.」が引数として指定されていると見なされます。デフォルトの生成先ディレクトリをオーバーライドするには、引き続き「-d
」を使用できます。
IDL および IIOP のスタブを生成するために、2 つの新しいオプション「-idl
」および「-iiop
」が追加されました。
rmid
(1.3 以降)rmid
(Solaris および Linux 用、Windows 用) は現在、セキュリティーポリシーファイルを要求します。java.rmi.StubNotFoundException
が発生しました。リモートオブジェクトの実装を対応するスタブに置換しようとしている最中に RMI ランタイムがスタブオブジェクトを見つけられなかった場合に、この例外が発生しました。1.2.2 以降のリリースでは、アンエクスポートされたリモートオブジェクトが RMI 呼び出しで渡されても例外とはならず、スタブではなく、リモートオブジェクトが直列化されます。リモートオブジェクトの実装が直列化できない場合、アンエクスポートされたオブジェクトを RMI 呼び出しで渡そうとすると、java.rmi.RemoteException
となります。この例外には、java.io.NotSerializableException
が入れ子にされています。