2003年度 データベース論

RMI
J2EE I
補講 / 2006-02-25
きょうの目標


分散オブジェクトの概念を理解する。
RMI の基本を理解する。
参考URL

JavaTM Remote Method Invocation
(RMI)


http://java.sun.com/j2se/1.5.0/ja/docs/ja/g
uide/rmi/index.html
Sun Microsystems による RMI の解説です。
分散オブジェクト
分散オブジェクト

ネットワーク的に離れたオブジェクト同士が
強調して動作するしくみのこと
分散オブジェクト技術






CORBA
DCOM
RPC ?
Java RMI
Peer to Peer (P2P) ?
などなど
RMI とは何か
RMI とは




Remote Method Invocation (遠隔メソッド
呼び出し) の略
違う Java Virtual Machine 上のメソッドを
呼び出す仕組みのこと
Java Virtula Machine は、別のホスト上に
あってもよい。
クライアント・サーバモデルとなる。
通常のJavaプログラムの場合


Hello クラスのインスタンスを作成する。
このインスタンスの sayHello メソッドを実
行する。
RMIの場合
RMI の場合




クライアントで Hello クラスのインスタンス
を作成する。
クライアントで、このインスタンスの
sayHello メソッドを実行する。
Hello クラスの実装はサーバ側にある。
サーバで sayHello メソッドが実行され、返
値がクライアントに返される。
RMI だと何がうれしいのか


Hello クラスの実装はサーバ側にあるので、
クライアントはサーバ側を呼び出すだけで
よい。
このときクライアントは、メソッドを実行する
だけでサーバを呼び出せる。
RMIのしくみ
サーバとクライアント


サーバでは、クライ
アントから呼び出さ
れるメソッドを実装
する。
クライアントでは、
サーバを見つけだ
して、メソッドを実行
する。
スタブとスケルトン


RMI では、通信に
必要な処理は「スタ
ブ」と「スケルトン」
というクラスに記述
される。
スタブとスケルトン
は、サーバのプロ
グラムから自動 or
ツールで生成され
る。
rmiregistry


サーバの情報を登
録しておくための
「ネームサーバ」
クライアントは
rmiregistry にアク
セスしてサーバの
プログラムを探す
RPC (Remote Procedure Call)




RMI の原型となった技術
Sun Microsystems によって開発された。
別のマシン上にある手続きを実行するた
めのしくみ。
Unix, Windows で広く普及している。
RMI を構成するプログラム
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 Server implements Hello {
......
}
サーバ側のプログラム (2)
クラスの定義

Hello インタフェースを実装する。
サーバ側のプログラム (3)
メソッド
public String sayHello() {
return "Hello world!";
}
サーバ側のプログラム (4)
メソッド

インタフェースで用意されたメソッドを実装
する。
サーバ側のプログラム (6)
mainメソッド (1)
// インスタンスを生成
Server obj = new Server();
// スタブを取得
Hello stub = (Hello)
UnicastRemoteObject.exportObject(obj, 0);
サーバ側のプログラム (7)
mainメソッド (2)
// rmiregistry にスタブを登録する
Registry registry =
LocateRegistry.getRegistry();
registry.bind("Hello", stub);
クライアント側のプログラム (1)
// rmiregistry から目的のスタブを探す
Registry registry =
LocateRegistry.getRegistry(host);
Hello stub = (Hello) registry.lookup("Hello");
クライアント側のプログラム (2)
// スタブの sayHello メソッドを実行する
String response = stub.sayHello();
RMI を動かす
プログラムのコンパイル



javac Hello.java
javac Server.java
javac Client.java
サーバ側とクライアント側で
用意するプログラム

サーバ側


Hello.class
Server.class

クライアント側


Hello.class
Client.class
rmiregistry の起動



start rmiregistry
このコマンドで rmiregistry を起動
起動するフォルダにはクラスファイルを置
かない
サーバの起動

java Server
クライアントの起動

java Client
スタブを事前に生成する方法
サーバ側のプログラム
mainメソッドの冒頭に
// 許可されてない操作を行わないために
if (System.getSecurityManager() == null)
{
System.setSecurityManager(
new RMISecurityManager()
);
}
スタブ (とスケルトン)の生成


rmic Server
このコマンドによって、次の2つのクラスが
生成される。


Server_Stub.class
rmic –keep Server を実行することで、スタ
ブのソースファイルを残すことができる。
サーバ側とクライアント側で
用意するプログラム

サーバ側




Hello.class
Server.class
スタブ
policy.txt (後述)

クライアント側



Hello.class
Client.class
policy.txt (後述)
サーバの起動 (1)
コマンドライン
java -Djava.rmi.server.codebase=
file:///C:\Home\rmi\
-Djava.security.policy=policy.txt
Server 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
Client localhost
注意点



Cygwin を使うとうまく動かない (原因は不
明)。
プログラムを起動するときには、クラスパス
を設定しないこと。
クラスパスを設定していると、もしクラスパ
ス中にスタブがあった場合、クライアントプ
ログラムはそのスタブをロードするから。