
Javaリモートメソッド呼び出し(Java RMI)は、リモートメソッド呼び出しを実行するJava APIであり、オブジェクト指向のリモートプロシージャコール(RPC)に相当し、シリアル化されたJavaクラスの直接転送と分散ガベージコレクションをサポートしています。
オリジナルの実装はJava仮想マシン(JVM)のクラス表現メカニズムに依存しているため、JVM間での呼び出しのみをサポートしています。このJava専用実装の基盤となるプロトコルは、Javaリモートメソッドプロトコル(JRMP)として知られています。JVM以外の環境でコードを実行できるようにするため、プログラマーは後にCORBA版を開発しました。
RMIという用語は、プログラミングインターフェースのみを指す場合もあれば、APIとJRMP、IIOP 、またはその他の実装の両方を指す場合もあります。一方、 RMI-IIOP (RMI over IIOPと読み替える)という用語は、RMIインターフェースの機能の大部分をサポートするCORBA実装に委譲することを具体的に示します。
Java RMIの基本的な考え方、分散ガベージコレクション(DGC)プロトコル、そしてオリジナルのSun実装の基盤となるアーキテクチャの多くは、Modula-3の「ネットワークオブジェクト」機能に由来しています。
オリジナルのRMI APIのプログラマーは、HTTPトランスポートなどのさまざまな実装をサポートするために、コードをある程度汎用化しました。さらに、RMIインターフェースとの互換性を保つために、CORBAには引数を値渡しする機能が追加されました。しかし、RMI-IIOPとJRMPの実装は、完全に同一のインターフェースを備えているわけではありません。
RMI 機能はパッケージに含まれていますjava.rmiが、Sun の実装の大部分はパッケージにありますsun.rmi。Java 5.0 より前のバージョンでは、開発者は を使用して RMI スタブを別のコンパイル手順でコンパイルする必要がありましたrmic。Java 5.0 以降ではこの手順は不要になり、静的スタブは Java 8 以降非推奨となっています。
JiniはJavaでRMIのより高度なバージョンを提供します。同様の機能を持ちながら、より高度なセキュリティ、オブジェクト検出機能、および分散オブジェクトアプリケーションのためのその他のメカニズムを提供します。[ 1 ]
以下のクラスは、RMIを使用してメッセージを表示するシンプルなクライアント/サーバープログラムを実装します。
RmiServerIntfインタフェースjava.rmi.Remote、実装クラスがリモートから呼び出し可能なメソッドを持つクラスであることを識別するインターフェースが拡張されます。パッケージorg.wikipedia.examples ;import java.rmi.Remote ; import java.rmi.RemoteException ;public interface RmiServerIntf extends Remote { String getMessage () throws RemoteException ; }RmiServerクラスパッケージorg.wikipedia.examples ;import java.rmi.Naming ; import java.rmi.RemoteException ; import java.rmi.server.UnicastRemoteObject ; import java.rmi.registry.* ;public class RmiServer extends UnicastRemoteObject implements RmiServerIntf { public static final String MESSAGE = "Hello World" ;public RmiServer () throws RemoteException { super ( 0 ); // 'rmic' ステップを回避するために必要。下記参照}public String getMessage () { return MESSAGE ; }public static void main ( String [] args ) throws Exception { System . out . println ( "RMI server started" );// レジストリ作成のための特別な例外ハンドラ try { LocateRegistry.createRegistry( 1099 ) ; System.out.println ( " Java RMIレジストリが作成されました。" ) ; } catch ( RemoteException e ) { //何もしない。エラーはレジストリが既に存在することを意味するSystem.out.println ( "Java RMI レジストリが既に存在します。" ); } // RmiServer をインスタンス化RmiServer server = new RmiServer ( );//このオブジェクトインスタンスを「 RmiServer」という名前にバインドします。 Naming.rebind ( " // localhost/RmiServer" , server ); System.out.println ( "PeerServer がレジストリにバインドされました" ); } }RmiClientクラスjava.io.Serializableの代わりにを実装した場合java.rmi.Remote、それはシリアル化されて値としてクライアントに渡されます。[ 2 ]パッケージorg.wikipedia.examples ;import java.rmi.Naming ;public class RmiClient { public static void main ( String [] args ) throws Exception { RmiServerIntf server = ( RmiServerIntf ) Naming . lookup ( "//localhost/RmiServer" ); System . out . println ( server . getMessage ()); } }この例を実行する前に、使用したインターフェース用の「スタブ」ファイルを作成する必要があります。このタスクには、RMIコンパイラ「rmic」を使用します。
rmic RmiServerJ2SE のバージョン 5.0 以降では、動的に生成されるスタブ ファイルのサポートが追加されており、rmic は以前のランタイムとの下位互換性[ 3 ] 、またはリモート オブジェクトのエクスポート時に明示的なポート番号(またはゼロ)を指定しないプログラムのためにのみ提供されています。これは、Javadocで説明されているように、生成されるスタブを可能にするために必要ですUnicastRemoteObject。上記のコンストラクタのコメントを参照してください。
java.rmi(RMIパッケージのJava APIリファレンス)