Remote Method Invocation
Download
Report
Transcript 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. その場で再編集