JDK 7 Update 21から、RMIプロパティjava.rmi.server.useCodebaseOnly
のデフォルト値はtrueに設定されています。詳細は、「JDK 7での拡張機能」を参照してください。
java.rmi.MarshalledObject
がジェネリックになりましたMarshalledObject
に、格納されている直列化されたオブジェクトの型を表す型パラメータが用意されました。RMIClientSocketFactory
を含むリモート・スタブでリモート呼出しが行われると、そのファクトリ・オブジェクトまたは等価なファクトリ・オブジェクトは仮想マシンで永久にアクセス可能なままとなっていました。そのため、そのオブジェクト(およびそのオブジェクトを定義するクラス・ローダー)はガベージ・コレクトされませんでした。このバグが修正されました。(リモート・オブジェクトのエクスポートに使用されるソケット・ファクトリの場合にも同様のバグ(6332603)があります。)sun.rmi.dgc.client.gcInterval
およびsun.rmi.dgc.server.gcInterval
によって制御される)は、デフォルトで1分でした。デフォルトの間隔は1時間になり、特別な構成がなくても、アプリケーションでサイズの大きいヒープを利用しやすくなりました。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サーバーを起動する(Java SE 5.0以降)System.inheritedChannel
メソッドにより提供される新しい機能によって、アプリケーションは、仮想マシン(VM)を起動したプロセスから継承されるチャネル(java.nio.channels.SocketChannel
またはjava.nio.channels.ServerSocketChannel
など)を取得することができます。この継承チャネルは、SocketChannel
の場合は単一の着信接続を行うため、ServerSocketChannel
の場合は複数の着信接続を受け入れるために使用できます。その結果、inetd
(Solarisオペレーティング・システム)またはxinetd
(Linux)によって起動されたJavaネットワーキング・アプリケーションは、inetd
/xinetd
から継承されたSocketChannel
またはServerSocketChannel
を取得できるようになりました。
この機能の追加によって、Java RMI起動デーモンrmid
は、着信した接続要求を受け取ったときにのみrmid
を起動できるように、inetd/xinetd
からの起動をサポートするように拡張されました。この機能をサポートするためのrmid
の拡張機能の詳細は、rmid
(Solaris、LinuxまたはMac OS Xオペレーティング・システム用)のツール・ページを参照してください。rmid
を起動するようにinetd
を構成する方法についての詳細は、「rmid
を起動するinetd
の構成」チュートリアルを参照してください。
Java RMIを使用するアプリケーションは、inetd
またはxinetd
から起動されるように設計することもできます。この技法を実装する方法の例については、「inetd
から起動されるサービスの設計」チュートリアルを参照してください。
rmic
の現在のデフォルトのスタブ・プロトコルのバージョン-v1.2
(Java SE 5.0以降)rmic
が実行されると、前のリリースの-vcompat
オプションの代わりに-v1.2
オプションが指定されているかのように実行されます。
つまり、この変更によって、デフォルトでは、rmic
はスケルトン・クラスは生成せず、1.2スタブ・プロトコルのバージョンだけを実装するスタブ・クラスを生成するようになりました。JDK 1.1で実行されるクライアントをサポートするためにリモート実装クラスを構築する必要がある場合は、-vcompat
オプションを明示的に指定する必要があります。(さらに、前述のようにリモート実装クラスがJava SE 5.0より前のバージョンで実行されるクライアントをサポートする必要がない場合は、そのようなクラスのためにrmic
を実行する必要はありません。)
これらのコマンド行オプションの詳細は、rmic
のツール・ドキュメント(Solaris、LinuxまたはMac OS X用、Windows用)を参照してください。
rmic
がクラス・パス内の任意のソース・ファイルをコンパイルすることはない(Java SE 5.0以降).java
ソース・ファイルをrmic
がコンパイルしようとすることがありました。Java SE 5.0では、rmic
は自ら生成したスタブ、スケルトンまたはタイ・クラス以外のソース・ファイルをコンパイルしようとすることはありません。
rmic
に渡されるリモート実装クラスは、そのクラスが依存しているすべてのクラスおよびインタフェースと同様に、rmic
が実行される前にすでにjavac
で正常にコンパイルされています。既存の構築手順が、一部のアプリケーション・ソース・ファイルをコンパイルするrmic
の以前の動作に依存している場合、その構築手順を修正し、rmic
を実行する前に、必要なすべてのクラスがjavac
で正しくコンパイルされるようにしてください。
この機能は、Java SE 1.4のjava.lang.Throwableの新しい「スタック・トレース情報へのプログラムによるアクセス」機能によって可能になりました。これには、デフォルトの直列化形式のThrowable
のスタック・トレース・データ部分の作成が含まれます。クライアント側Java RMIランタイム実装は、この機能と連携するために、以前のリリースのように単にクライアント側トレースで上書きするのではなく、クライアント側トレースを非整列化されたサーバー側トレースに追加します。
特定のサーバー・アプリケーションでは、パフォーマンスや機密上の理由により、Java SE 1.4での例外のデフォルトの直列化形式の一部としてリモート呼出しにより直列化される例外がサーバー側スタック・トレース・データで発生しないようにする場合があります。そのような場合は、実装に固有のシステム・プロパティである
sun.rmi.server.suppressStackTracesを「true」に設定すると、サーバー側Java RMIランタイム実装によって、リモート・メソッドの呼出しの結果、現在の仮想マシンからスローされたすべての例外のスタック・トレースが消去されます。
RMIClassLoader
用サービス・プロバイダ・インタフェース(Java SE 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
メソッドは返される名前にスキームを付加することはない(Java SE 1.4.1以降)Naming.list
メソッドは、返された文字列の配列に含まれる名前にスキームrmi:
を付加していました。現在のNNaming.list
の実装はその仕様に合致しており、URL形式の名前の配列を返しますが、スキーム・コンポーネントは含まれません。java.rmi.activation.ActivationGroupDesc
(Java SE 1.3以降)getClassName
メソッドが、システムのデフォルト・グループ実装を示すnull
を返すことが可能になりました。これまでは、記述子の構築時にデフォルトのグループ実装が選択された場合、getClassName
メソッドは内部の実装クラスの名前を返していました。
この変更に対応するために、Java SE 1.3の仮想マシンで稼働するアプリケーションが新たな起動可能オブジェクトをActivationSystem
に登録する場合、rmid
もJava SE 1.3を実行できるようにアップグレードする必要があります。これは、1.3より前のrmid
では新たに登録された起動可能オブジェクトを起動できないためです。
rmic
(Java SE 1.3以降)rmic
(Solaris、LinuxまたはMac OS X用、Windows用)では、スタブのデフォルトの生成先ディレクトリが、パッケージ名の付いた、現在の作業ディレクトリのサブディレクトリになりました。「-d
」オプションを指定しない場合は、現在の作業ディレクトリ「.」が引数として指定されていると見なされます。デフォルトの生成先ディレクトリをオーバーライドするには、引き続き「-d
」を使用できます。
IDLおよびIIOPのスタブを生成するために、2つの新しいオプション「-idl
」および「-iiop
」が追加されました。
rmid
(Java SE 1.3以降)rmid
(Solaris、LinuxまたはMac OS X用、Windows用)は現在、セキュリティ・ポリシー・ファイルを要求します。java.rmi.StubNotFoundException
が発生しました。リモート・オブジェクトの実装を対応するスタブに置換しようとしている最中にRMIランタイムがスタブ・オブジェクトを見つけられなかった場合に、この例外が発生しました。Java SE 1.2.2以降のリリースでは、アンエクスポートされたリモート・オブジェクトがRMI呼出しで渡されても例外とはならず、スタブではなく、リモート・オブジェクトが直列化されます。リモート・オブジェクトの実装が直列化できない場合、アンエクスポートされたオブジェクトをRMI呼出しで渡そうとすると、java.rmi.RemoteException
となります。この例外には、java.io.NotSerializableException
が入れ子にされています。