Remote Method Invocation

Remote Method Invocation
00k1126 Hiroko Suzuki
RMI概要

Remote Method Invocation
→遠隔メソッド呼び出し
異なるJVM上に存在するオブジェクトのMethod
を呼び出す機能を実現するための仕組みである
RMI概要Ⅱ



通信の部分のコードを意識せずにサーバ・
クライアントの機能を実現できる
JDK1.1以降で標準ライブラリとして提供さ
れている(JDK1.3.0使用)
Methodを呼び出す際の引数・戻り値として、
オブジェクトを受け渡すことが出来る
RMIの仕組み



ServerとClientはinterfaceで結合される
ServerはClientに対してオブジェクトの参照
(どのMethodが参照可能か)を提供し、
Clientはその参照を用いてServerのMethod
を呼び出す
上記の機能を成り立たせるためにRegistry
を使用する
RMIRegistry



名前付けされたRemote Objectの登録・検索を行
うネームサーバである
RMIのオブジェクトは一意のURLと名前で登録さ
れ、サービスの呼び出しはこのRegistryへの問い
合わせによって開始される
RMIのプログラムの実行時にはRMIRegistryが
バックグラウンドで起動している必要がある
RMI Application 作成手順


Server側
1. Remote Object のInterfaceを作成
2. Remote Object の実装(1.のInterfaceを
Implementする)
Client側
3. Remote Objectを使うClientを実装
RMI Application 実行手順


ソースコードのコンパイル
リモートオブジェクトのコンパイル
これによって新しいバイトコードが2つ生成
される(StubとSkel)
簡単な例での実装
Example(basic) – Server 側
1. Remote ObjectのInterfaceの定義
Remote Interface はRemoteのサブクラスである
Remote Method の定義を記述し、また、RemoteMethod
はRemoteExceptionをthrowしなければならない
import java.rmi.*;
interface HelloWorld extends Remote {
String sayHelloWorld( String name )
throws RemoteException;
}
Example(basic) – Server 側
2. Remote Objectの作成
・UnicastRemoteObjectを継承し、RemoteInterfaceを
実装する HelloWorldObj.java
public class HelloWorldObj
extends UnicastRemoteObject
implements HelloWorld
Example(basic) – Server 側
・ Superclass であるUnicastRemoteObjectのコンスト
ラクタがRemoteExceptionを送出するので、コンス
トラクタを作成し、RemoteExceptionをthrowするよ
うにする
// コンストラクタ
public HelloWorldObj() throws RemoteException { }
Example(basic) – Server 側
・RMIを利用可能にするためにセキュリティマネ
ジャの設定
・RMIRegistryへの登録 HelloWorldObj.java
// セキュリティマネージャーの設定
System.setSecurityManager
( new RMISecurityManager() );
// サーバー側のリモートオブジェクトを生成
HelloWorldObj obj = new HelloWorldObj();
// リモートオブジェクトに新しい名前を関連付ける
Naming.rebind( "MyObject", obj );
Example(basic) – Client 側
・ Clientのプログラムを作成し、その中でRemote
Objectの名前を引数にしてNaming.lookup
Methodを呼ぶ
Web Server に入れてアクセスさせる場合は
localhost の部分にIPaddress もしくはaddressを記
述する
•// リモートオブジェクトの参照(スタブ)を取得します
obj = ( HelloWorld )Naming.lookup
( "rmi://localhost/MyObject" );
Example(basic) – Compile


全体のソースコードをCompile
C:\> javac *.java
Remote Object の Compile
C:\ rmic HelloWorldObj
この結果、 HelloWorldObj_Skel.class(スケルトン)と
HelloWorldObj_Stub.class(スタブ)がディレクトリ内に生
成される。実際に異なるJVMで通信を行うのはこの二つ
のクラスである。
Example(basic) – Security Policy

動くことを前提にすべてを許可するコードを書くこ
とにする
このファイル名をpolicyとする
grant {
permission java.security.AllPermission;
};
Example(basic) – 実行


NameServerの起動
C:\RmiRegistry > rmiregistry
正常に起動された場合はカーソルが点滅した状
態になる
RMIServer の起動
実行時に-Dオプションでプロパティの設定をする
C:\RMI>java -Djava.security.policy=java.policy
-Djava.rmi.server.codebase=
file:///C:/RMI/ HelloWorldObj
Example(basic) – エラー例

java.rmi.ConnectException:
Connection refused to host: xxx.xxx.x.xx(IPAddress)
RMIRegistry が起動していない

java.rmi.AlreadyBoundException: Server
Serverという名前のRMIServerがRMIRegistry にもうすでに登録され
ている

java.security.AccessControlException: access denied
(java.net.SocketPermission xxx.xxx.x.xxx:xxxx connect,resolve)
セキュリティポリシーの設定のエラー
Example(basic) – 実行

Client プログラムを実行する
C:\RMI> java –Djava.security.policy=policy
HelloWorldClient name
Hello name!! と表示されたら成功
Example(basic) – エラー例

java.rmi.ConnectException:
Connection refused to host: xxx.xxx.x.xx(IPAddress)
Naming.lookup( “rmi://” + addr + “/Server”);
addressの記述ミス
名前の記述ミス
RMIServerが起動していない
Schedule Management System
Schedule Management System


Host上の全ユーザの個人もしくはグループ
のスケジュールを管理するシステム
スケジュールの形態
2003/4/30
開始時刻
終了時刻
内容
メモ
13:30
14:30
Meeting
@lab
18:30
19:50
Lesson
w4021
Schedule Management System
見た目
Schedule Management System

Server
Userの管理
Scheduleの管理

Client
Scheduleの取得・編集
Schedule Management System
ScheduleのAppointment Object :
Appointment.class
public int start;
//start time
public int end;
//end time
public String description;
public String memo;
//memo
public Appointment( int sh, int sm, int eh, int em,
String descrip, String me ) {
start = sh * 60 + sm;
end = eh * 60 + em;
description = descrip;
memo = me;
}
Schedule Management System
ServerはClientのScheduleをHashTableで管理する
“2003/4/30”という日付の文字列をKeyとし、
その日のアポイントメントの配列(Appointmentを要素とす
るVector)を値とするHashTable
そのHashTableを値とし、UserNameをKeyとしたHashTable
でGroupのScheduleを管理する
Schedule Management System
Clientは個人のScheduleを選択し今日の日付のScheduleを得る
( Server側のgetDailyApp() Methodを呼ぶ )
ScheduleImpl.java
public synchronized Vector
getDailyApp( String usr,
int year,
int month,
int day )
throws RemoteException {
table = new Hashtable();
Object users=user.get(usr);
if( users != null ){
table = ( Hashtable )users;
String key =
getKey( year,month, day );
Object obj = table.get( key );
if( obj == null ) return null;
else return ( Vector )obj;
}else return null;
}
Schedule Management System
Scheduleを編集し、Updateする場合はServer側のupdateDailyApp
Methodを呼ぶ。ServerはsendData Methodで同じScheduleを
参照しているClientにCallbackで変更を知らせる( sendData() )
ScheduleImpl.java
public synchronized void
updateDailyApp( String usr,
int ye,
int mo,
int da,
Vector v )
throws RemoteException {
Object users=user.get( usr );
if( users != null )
table = ( Hashtable )users;
String key =
getKey( ye, mo, da );
table.put( key, v );
user.put( usr, table );
sendData( usr, key, v );
}
Schedule Management System
ServerからClientのメソッドを呼び出す ScheduleImpl.java
WhatDaysSch() と outUpdate( Vector v ) メソッドはClient側のメ
ソッドである( RemoteExceptionをthrowしている必要がある )
private void sendData( String usr, String key, Vector v ){
try{
InterfaceClient cl; String str;
int rsize = remote_obj.size();
for( int i=0; i<rsize; i++ ){
str = ( String )member.get( i );
if( str.equals( usr )){
cl = ( InterfaceClient )remote_obj.get( i );
if( key.equals( cl.WhatDaysSch() ) ){
cl.outUpdate( v );
}}}
}catch( Exception e ){
e.printStackTrace();
}}
Conflictを避けるには

Conflictを避けるには
1. TimeTable上のクリックした時間だけedit不可にする
→1 Day Schedule の編集の柔軟性を高める
2. Edit WindowでそのAppointmentの優先度を選択出来るようにする

重要度で置き換えられたAppointment はどうするか?
1. 近い時間に移動する
2. 削除されたAppointmentを保管しておくVectorを作る
指定した時間後にそのデータを破棄する
3. その場で再編集