1 / 24

Java Distributed Objects 1

Java Distributed Objects 1. Masayuki Iwai tailor@ht.sfc.keio.ac.jp. 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 限

yahto
Download Presentation

Java Distributed Objects 1

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Java Distributed Objects1 Masayuki Iwai tailor@ht.sfc.keio.ac.jp

  2. 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限 • Jini programming • Java Space programming • Distributed Objectsの世界

  3. Distibuted objectsの目指す世界 • タスクの依頼 • 自由な連携 take write take read write

  4. Local Method Invocation LocalMainClass LocalRuntime 192.168.0.1 • Local Method Invocation LocalClass localClass=new LocalClass(); outputObj=localClass.method(inputObj); • inputObjはprimitive型でない限りcall by referenceとして渡される。

  5. メソッドの引数と返り値について • call by reference • 参照渡し • call by value • 値渡し

  6. CallbyTestMain package jp.ac.sfc.keio.sfc.tailor.callbyLocal; publicclass CallbyTestMain extends Thread { String str = "0"; StringBuffer sbuf = new StringBuffer("0"); int i = 0; TestObj obj = new TestObj(); publicstaticvoid main(String args[]) { CallbyTestMain calltester = new CallbyTestMain(); calltester.start(); } publicvoid 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(); } }

  7. CallTesterLocalMethods package jp.ac.sfc.keio.sfc.tailor.callbyLocal; publicclass CallTesterLocalMethods { privateint 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); } publicvoid setStringBuffer(StringBuffer sbuf) { this.sbuf=sbuf; } void printStringBuffer() { System.out.println("StringBuffer:"+sbuf); } void setObject(TestObj obj) { this.obj = obj; } void printObject() { obj.printTestObj(); } }

  8. TestObj package jp.ac.sfc.keio.sfc.tailor.callbyLocal; publicclass TestObj { privateint i=0; publicvoid increment(){ i++; } publicvoid printTestObj(){ System.out.println("Object:"+i); } }

  9. 動きを予想してみよう。 Primitive:0 String:0 StringBuffer:0 Object: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:【 】

  10. RMI:Remote Method Invocation RemoteClass LocalMainClass method LocalRuntime RemoteRuntime 192.168.0.1 192.168.0.2 Remote Classのmethodを Callbyreferenceで呼びたいのがRMI

  11. RMI:OutputStream • ソケットの作成が必要 • Bytedataのみをコピー可能 A B ByteData OutputStream VM_A VM_B

  12. RMI:ObjectOutputStream • java.io.Serializableを実装したオブジェクト • Objectを一時直列化しネットワークを経由してコピーを行う • BがCをよみがえらせるには,Cのクラスファイルが必要 C C A B 0100101001010 ObjectOutputStream VM_A VM_B

  13. Dateオブジェクトの移動 • Dateクラスは、Serializableインターフェースを実装している。 • 直列化可能という意味のマークキングインタフェース • Methodは持たない。 • 移動させたいObjectクラス定義の際に、 Serializable を実装

  14. Interfaceによるremoteでのオブジェクト復元 • Inferfaceでキャストすることで • //Mony money= new MonyImpl(); • Mony money= new MonyImpl2(); 移動オブジェクトの実装変更が可能 呼び出し先では常に • Mony money = (Mony) (ois.readObject()); • money.printMoney(); • money.increment(); しかし、objectの移動にもかかわらずcall by referenceでない。

  15. Castは万能か? • 実はディレクトリを分けると • 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クラスがいるのだ

  16. NetworkClassLoaderで実装クラスを呼び寄せる。 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(); } } }

  17. rmic -v1.2 MoneyRemoteImple • start rmiregistry • rmiregistry & • java -Djava.rmi.server.codebase=file:/C:workspace\ -Djava.security.policy=policy.txt MoneyRemoteImple

  18. RMI:Bの側にCのクラスファイルがない場合RMI:Bの側にCのクラスファイルがない場合 • Interfaceを利用したCastだけではだめ • BはCを保持しておく必要がないが最終的にはCの情報が必要->NetworkClassLoader Cの情報をダウンロード C NetworkClassServer NetworkClassLoader interface C C C’ A serializable B C 0100101001010 ObjectOutputStream VM_A VM_B

  19. RMI:すこし立ち止まって • クラスサーバは果たしてLocalRuntimeにある必要はあるのか? Cの情報をダウンロード C NetworkClassServer NetworkClassServer interface C C C’ A serializable B C 0100101001010 ObjectOutputStream VM_A VM_B

  20. RMI:Marshalled Object • MarshalledObject=serialized object+そのロード元 (可能な場合) となるコードベース URL • BはCを知る必要がない:webserverは何処にあってもよい:動作はVM_B上 C http/get websrver Cクラスの解決情報 C C C C C’ A serializable B ObjectOutputStream VM_A VM_B

  21. RMI: 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 */ }

  22. RMI:Object I/O Streamの2つの問題 • オブジェクト単位 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); AccountクラスってRemoteに最新のものあるの? これって変更されるのRemoteのAccountクラスだよね

  23. RMI: • Socket/ObjectStreamレベルのことはStabが行う。 • Stabクラスはrmic –v1.2 ServerClassのコマンドで生成 • 実はMarshalledObjectを利用してRMIは実装されている。 • コードベースのためWebserverが必要 • スタブオブジェクトが必要:動作はVM_A上 C クラスCは必要ない WEBSERVER インタフェースC’ UnicastRemoteObject C C C’ A C_stub C_stub B RMI VM_A VM_B

  24. RMI:SocketProgrammingではない。 =================サーバ側 VM_A=================== public class AccountImpleextends 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プログラミングあらたな問題

More Related