410 likes | 560 Views
RMI. ソフトウェア特論 第 6 回 / 2004-06-04. お知らせ. 6 月 11 日 ( 金 ) の講義は休講となります。. きょうの目標. RMI の基本を復習する。. RMI とは何か. RMI とは. Remote Method Invocation ( 遠隔メソッド呼び出し ) の略 違う Java Virtual Machine 上のメソッドを呼び出す仕組みのこと Java Virtula Machine は、別のホスト上にあってもよい。 クライアント・サーバモデルとなる。. 通常の Java プログラムの場合.
E N D
RMI ソフトウェア特論 第6回 / 2004-06-04
お知らせ • 6月11日 (金) の講義は休講となります。
きょうの目標 • RMI の基本を復習する。
RMI とは • Remote Method Invocation (遠隔メソッド呼び出し) の略 • 違う Java Virtual Machine 上のメソッドを呼び出す仕組みのこと • Java Virtula Machine は、別のホスト上にあってもよい。 • クライアント・サーバモデルとなる。
通常のJavaプログラムの場合 • Hello クラスのインスタンスを作成する。 • このインスタンスの sayHello メソッドを実行する。
RMI の場合 • クライアントで Hello クラスのインスタンスを作成する。 • クライアントで、このインスタンスの sayHello メソッドを実行する。 • Hello クラスの実装はサーバ側にある。 • サーバで sayHello メソッドが実行され、返値がクライアントに返される。
RMI だと何がうれしいのか • Hello クラスの実装はサーバ側にあるので、クライアントはサーバ側を呼び出すだけでよい。 • このときクライアントは、メソッドを実行するだけでサーバを呼び出せる。
サーバとクライアント • サーバでは、クライアントから呼び出されるメソッドを実装する。 • クライアントでは、サーバを見つけだして、メソッドを実行する。
スタブとスケルトン • RMI では、通信に必要な処理は「スタブ」と「スケルトン」というクラスに記述される。 • スタブとスケルトンは、サーバのプログラムからツールで生成される。
rmiregistry • サーバの情報を登録しておくための「ネームサーバ」 • クライアントは rmiregistry にアクセスしてサーバのプログラムを探す
RPC (Remote Procedure Call) • RMI の原型となった技術 • Sun Microsystems によって開発された。 • 別のマシン上にある手続きを実行するためのしくみ。 • Unix, Windows で広く普及している。
Remoteインタフェース (1) import java.rmi.Remote; import java.rmi.RemoteException; public interface Hello extends Remote { public String sayHello() throws RemoteException; }
Remoteインタフェース (2) • クライアントから呼び出せるメソッドを定義する。 • サーバは、このインタフェースを実装する。 • このインタフェースをサーバとクライアントで共有する。 • java.rmi.Remote を継承する。 • それぞれのメソッドは、RemoteException を発行できるようにする。
サーバ側のプログラム (1)クラスの定義 public class HelloImpl extends UnicastRemoteObject implements Hello { ...... }
サーバ側のプログラム (2)クラスの定義 • Hello インタフェースを実装する。 • UnicastRemoteObject を継承する。
サーバ側のプログラム (3)コンストラクタとメソッド public HelloImpl() throws RemoteException { super(); } public String sayHello() throws RemoteException { return "Hello world!"; }
サーバ側のプログラム (4)コンストラクタとメソッド • RemoteException を発行するようにする。 • そのため、必ずコンストラクタを用意しなければならない。 • インタフェースで用意されたメソッドを実装する。
サーバ側のプログラム (5)mainメソッド (1) // 許可されてない操作を行わないために if (System.getSecurityManager() == null) { System.setSecurityManager( new RMISecurityManager() ); }
サーバ側のプログラム (6)mainメソッド (2) // インスタンスを生成 HelloImpl obj = new HelloImpl(); // rmi://localhost/HelloServerといった // URIを生成する StringBuffer url = new StringBuffer(); url.append("rmi://"); url.append(args[0]); url.append("/HelloServer");
サーバ側のプログラム (7)mainメソッド (3) // rmiregistry に // HelloImpl を // rmi://localhost/HelloServer という名前で // 登録する Naming.rebind(new String(url), obj);
クライアント側のプログラム (1) // rmi://localhost/HelloServerといった // URIを生成する StringBuffer url = new StringBuffer(); url.append("rmi://"); url.append(args[0]); url.append("/HelloServer");
クライアント側のプログラム (2) // rmiregistry から // rmi://localhost/HelloServer という名前の // オブジェクトを探し、Hello にキャストする Hello obj = (Hello)Naming.lookup( new String(url));
クライアント側のプログラム (3) // Hello オブジェクトの // sayHello メソッドを実行する System.out.println(obj.sayHello());
プログラムのコンパイル • javac Hello.java • javac HelloImpl.java • javac HelloClient.java
スタブとスケルトンの生成 • rmic HelloImpl • このコマンドによって、次の2つのクラスが生成される。 • HelloImpl_Stub.class • HelloImpl_Skel.class • rmic –keep HelloImpl を実行することで、スタブとスケルトンのソースファイルを残すことができる。
サーバ側 Hello.class HelloImpl.class スタブ スケルトン policy.txt (後述) クライアント側 Hello.class HelloClient.class policy.txt (後述) サーバ側とクライアント側で用意するプログラム
rmiregistry の起動 • start rmiregistry • このコマンドで rmiregistry を起動 • 起動するフォルダにはクラスファイルを置かない
サーバの起動 (1)コマンドライン java -Djava.rmi.server.codebase= file:///C:\Home\rmi\ -Djava.security.policy=policy.txt HelloImpl localhost
サーバの起動 (2)codebase (1) java.rmi.server.codebase= file:///C:\Home\rmi\ • codebase プロパティでスタブの位置を指定する。 • この場合は、C:\Home\rmi\ にスタブを置いておく。
サーバの起動 (3)codebase (2) • C:\Home\rmi\ • 最後の \ を忘れない • Codebase には Web上の URL を指定することもできる。 • http://www.wakhok.ac.jp/~tomoharu/ • この URL にスタブを置いておく
サーバの起動 (4)codebase (3) • クライアントが起動されると、codebase で指定された URL からスタブがダウンロードされて、クライアントプログラムからスタブを利用できるようになる。
サーバの起動 (5)ポリシーファイルの設定 java.security.policy=policy.txt • policy.txt というファイルでアクセス権を指定できる。
サーバの起動 (6)policy.txt の内容 grant { // Allow everything for now permission java.security.AllPermission; }; • すべての人にすべてのアクセス権を与える
クライアントの起動 • java -Djava.security.policy=policy.txt HelloClient localhost
注意点 • Cygwin を使うとうまく動かない (原因は不明)。 • プログラムを起動するときには、クラスパスを設定しないこと。 • クラスパスを設定していると、もしクラスパス中にスタブがあった場合、クライアントプログラムはそのスタブをロードするから。
参考文献・URL • JavaTM Remote Method Invocation (RMI) • http://java.sun.com/j2se/1.4/ja/docs/ja/guide/rmi/ • Sun Microsystems による RMI の解説です。