java distributed objects 1
DESCRIPTION
Java Distributed Objects 1. Masayuki Iwai [email protected]. Table of contents. 第 1 回 10 月 11 日木曜日 5 限 Distibuted objects の目指す世界 Rmi 以前 tutorial Rmi tutorial 第 2 回 10 月 19 日金曜日 6 限 Rmi Advanced tutorial Rmi tutorial custom socket package Activatable 第 3 回 10 月 17 日木曜日 5 限 - PowerPoint PPT PresentationTRANSCRIPT
©Msayuki Iwai
Table of contentsTable of contents
• 第 1 回 10 月 11 日木曜日 5 限– Distibuted objects の目指す世界– Rmi 以前 tutorial– Rmi tutorial
• 第 2 回 10 月 19 日金曜日 6 限• Rmi Advanced tutorial
– Rmi tutorial– custom socket package– Activatable
• 第 3 回 10 月 17 日木曜日 5 限– Jini programming– Java Space programming– Distributed Objects の世界
©Msayuki Iwai
Distibuted objectsDistibuted objects の目指す世界の目指す世界• タスクの依頼• 自由な連携 take
readwrite
take
write
©Msayuki Iwai
Local Method InvocationLocal Method Invocation
• Local Method InvocationLocalClass localClass=new LocalClass();
outputObj=localClass.method(inputObj);
– inputObj は primitive 型でない限りcall by reference として渡される。
LocalRuntime
LocalMainClass
192.168.0.1
©Msayuki Iwai
メソッドの引数と返り値についてメソッドの引数と返り値について• call by reference
– 参照渡し
• call by value– 値渡し
©Msayuki Iwai
CallbyTestMainCallbyTestMainpackage jp.ac.sfc.keio.sfc.tailor.callbyLocal;
public class CallbyTestMain extends Thread {
String str = "0";StringBuffer sbuf = new StringBuffer("0");int i = 0;TestObj obj = new TestObj();
public static void main(String args[]) {
CallbyTestMain calltester = new CallbyTestMain();
calltester.start();
}
public void run() {
CallTesterLocalMethods funcs = new CallTesterLocalMethods();
funcs.setStringBuffer(sbuf);funcs.setString(str);funcs.setPrimitive(i);funcs.setObject(obj);
System.out.println("Primitive:"+i);System.out.println("String:"+str);System.out.println("StringBuffer:"+sbuf);obj.printTestObj();
System.out.println("=========== LOOP START============");
while (i < 4) {
{i++;str=""+i;sbuf.append(i);obj.increment();}
System.out.println("----------------------------------");
funcs.printPrimitive();funcs.printString();funcs.printStringBuffer();funcs.printObject();
try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO 自動生成された catch ブロックe.printStackTrace();}
}//whie end
System.out.println("=========== LOOP END============");
System.out.println("Primitive:"+i);System.out.println("String:"+str);System.out.println("StringBuffer:"+sbuf);obj.printTestObj();
}
}
©Msayuki Iwai
CallTesterLocalMethodsCallTesterLocalMethodspackage jp.ac.sfc.keio.sfc.tailor.callbyLocal;
public class CallTesterLocalMethods {
private int i;private String str;private StringBuffer sbuf;private TestObj obj;
void setPrimitive(int i) {this.i = i;}
void printPrimitive() {System.out.println("Primitive:" + i);}
void setString(String str) {this.str = str;}
void printString() {System.out.println("String:"+str);}
public void setStringBuffer(StringBuffer sbuf) {this.sbuf=sbuf;
}
void printStringBuffer() {System.out.println("StringBuffer:"+sbuf);}
void setObject(TestObj obj) {this.obj = obj;}
void printObject() {obj.printTestObj();}
}
©Msayuki Iwai
TestObjTestObjpackage jp.ac.sfc.keio.sfc.tailor.callbyLocal;
public class TestObj {
private int i=0;
public void increment(){i++;}
public void printTestObj(){System.out.println("Object:"+i);}
}
©Msayuki Iwai
動きを予想してみよう。動きを予想してみよう。Primitive:0String:0StringBuffer:0Object:0=========== LOOP START============----------------------------------Primitive: 【 】String: 【 】StringBuffer: 【 】Object: 【 】----------------------------------Primitive: 【 】String: 【 】StringBuffer: 【 】Object: 【 】----------------------------------Primitive: 【 】String: 【 】StringBuffer: 【 】Object: 【 】----------------------------------Primitive: 【 】String: 【 】StringBuffer: 【 】Object: 【 】=========== LOOP END============Primitive: 【 】String: 【 】StringBuffer: 【 】Object: 【 】
©Msayuki Iwai
RMIRMI :: Remote Method InvocationRemote Method Invocation
LocalRuntime
LocalMainClass
192.168.0.1
RemoteClass
RemoteRuntime
method
192.168.0.2
Remote Class の method をCallbyreference で呼びたいのが RMI
©Msayuki Iwai
RMI:OutputStreamRMI:OutputStream
• ソケットの作成が必要• Bytedata のみをコピー可能
A B
OutputStream
ByteData
VM_A VM_B
©Msayuki Iwai
RMI:ObjectOutputStreamRMI:ObjectOutputStream• java.io.Serializable を実装したオブジェクト• Object を一時直列化しネットワークを経由し
てコピーを行う• B が C をよみがえらせるには, C のクラス
ファイルが必要
A B
ObjectOutputStream
C C0100101001010
VM_A VM_B
©Msayuki Iwai
DateDate オブジェクトの移動オブジェクトの移動• Date クラスは、 Serializable インター
フェースを実装している。
• 直列化可能という意味のマークキングインタフェース– Method は持たない。
• 移動させたい Object クラス定義の際に、 Serializable を実装
©Msayuki Iwai
InterfaceInterface によるによる remoteremote でのオブジェでのオブジェクト復元クト復元
• Inferface でキャストすることで• //Mony money= new MonyImpl();• Mony money= new MonyImpl2();移動オブジェクトの実装変更が可能
呼び出し先では常に• Mony money = (Mony) (ois.readObject());
• money.printMoney();• money.increment();
しかし、 object の移動にもかかわらず call by reference でない。
©Msayuki Iwai
CastCast は万能か?は万能か?• 実はディレクトリを分けると• Remote 側で以下のエラーがおこる。
– java.lang.ClassCastException: jp.ac.sfc.keio.sfc.tailor.remote.withinterface2.local.MonyImpl2 cannot be cast to jp.ac.sfc.keio.sfc.tailor.remote.withinterface2.remote.Mony
のInferace だけではだめ実はキャスト ( オブジェクト復元 ) には imple
クラスがいるのだ
©Msayuki Iwai
NetworkClassLoaderNetworkClassLoader で実装クラスを呼び寄で実装クラスを呼び寄せる。せる。
import java.util.*;import java.io.*;import java.net.*; public class NetworkClassLoader extends
ClassLoader {
InputStream in = null; ByteArrayOutputStream out = new
ByteArrayOutputStream(1024); public NetworkClassLoader(){ this("localhost",8081); }
public NetworkClassLoader(String host, int port){
try { Socket s = new
Socket(host,port); in = s.getInputStream(); } catch (Throwable e) { e.printStackTrace(); } }
protected Class findClass( String name ) throws ClassNotFoundException {
try { byte buff[] = new byte[1024]; int n,m; int len=0; while ((n = in.read(buff, 0 ,
1024)) >= 0) { out.write(buff,0,n); len += n ; } byte data[] = new byte[len]; data=out.toByteArray(); return
defineClass(null, data, 0, len);
} catch (Throwable e) { e.printStackTrace(); throw new
ClassNotFoundException(); } } }
©Msayuki Iwai
• rmic -v1.2 MoneyRemoteImple• start rmiregistry • rmiregistry &• java -
Djava.rmi.server.codebase=file:/C:workspace\ -Djava.security.policy=policy.txt MoneyRemoteImple
•
©Msayuki Iwai
RMI:RMI: BB の側にの側に CC のクラスファイルがない場合のクラスファイルがない場合
• Interface を利用した Cast だけではだめ
• B は C を保持しておく必要がないが最終的には C の情報が必要 ->NetworkClassLoader
A B
ObjectOutputStream
C Cserializable C’
C の情報をダウンロード
interface
0100101001010
NetworkClassServer NetworkClassLoaderC
C
VM_A VM_B
©Msayuki Iwai
RMI:RMI: すこし立ち止まってすこし立ち止まって• クラスサーバは果たして
LocalRuntime にある必要はあるのか?
A B
ObjectOutputStream
C Cserializable C’
C の情報をダウンロード
interface
0100101001010
NetworkClassServer NetworkClassServerC
C
VM_A VM_B
©Msayuki Iwai
RMI:Marshalled ObjectRMI:Marshalled Object
• MarshalledObject=serialized object+ そのロード元 ( 可能な場合 ) となるコードベース URL
• B は C を知る必要がない :webserver は何処にあってもよい:動作は VM_B 上
A BObjectOutputStream
C serializable C’
C クラスの解決情報C
CC
websrver
Chttp/get
VM_A VM_B
©Msayuki Iwai
RMI: MarshalledObjectRMI: MarshalledObject の実装の実装public final class MarshalledObject implements Serializable { /** * @serial Bytes of serialized representation. If <code>objBytes</code> is * <code>null</code> then the object marshalled was a
<code>null</code> * reference. */ private byte[] objBytes = null;
/** * @serial Bytes of location annotations, which are ignored by * <code>equals</code>. If <code>locBytes</code> is null, there were
no * non-<code>null</code> annotations during marshalling. */ private byte[] locBytes = null;
/** * @serial Stored hash code of contained object. * * @see #hashCode */}
©Msayuki Iwai
RMI:Object I/O StreamRMI:Object I/O Stream のの 22 つの問題つの問題– オブジェクト単位 public class Account implements Serializable{
public void setMoney(){….}
public Money getMony(){….}
public void addMony(){….}
public void subMony(){….}
}
================= 書き出す側 VM_A===================
Socket s = ss.accept();
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
Account acc= Bank.getAccount(me);
oos.writeObject(acc);
s.close();
================= 読み出す側 VM_B===================
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
Account acc= (Account) (ois.readObject());
acc.addMony(1000);
これって変更されるのRemoteの Account クラスだよねAccount クラスってRemoteに最新のものあるの?
©Msayuki Iwai
RMIRMI ::• Socket/ObjectStream レベルのことは Stab が行う。• Stab クラスは rmic –v1.2 ServerClass のコマンド
で生成– 実は MarshalledObject を利用してRMIは実装されている。– コードベースのため Webserver が必要– スタブオブジェクトが必要:動作は VM_A 上
VM_A VM_B
A B
RMI
CUnicastRemoteObject
C’C_stub C_stub
WEBSERVER
C クラスCは必要ない
インタフェースC’C
©Msayuki Iwai
RMI:SocketProgrammingRMI:SocketProgramming ではない。ではない。
================= サーバ側 VM_A===================public class AccountImple extends UnicastRemoteObject
implements IAccount{}
AccountImple acc= Bank.getAccountImple (me); Naming.rebind(“registryhostname/Account_Iwai”,acc);
起動方法>>java MainClass
java.rmi.server.codebase=http://codebasehost/accout.jar
================= クライアンド側 VM_B===================
String location = "rmi://registryhostname/Account_Iwai" ;acc=(IAccount)Naming.lookup(location); acc.addMony(1000);
Socket プログラミングあらたな問題