1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

36
1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell

Transcript of 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

Page 1: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

1

Remote Method Invocation

(RMI) and Distributed Observers in JavaTheodore Norvell

Page 2: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 2

The Proxy Pattern

The Client object uses its subject via an interface Thus it may be used with a real subject or with a

proxy object which represents the subject.

Page 3: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 3

The Proxy Pattern

The client calls the proxy, which

forwards the call (somehow) to the actual subject.

someObject : Client p : ProxyClass : Subject

operation( )

operation( )

setSubject(p)

Page 4: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 4

RMI and the Proxy pattern

RMI uses the Proxy pattern to distribute objects across a network.

Recall that in the Proxy pattern a proxy and a subject share a common interface.

In RMI, objects call methods in a proxy (aka stub) on its own machine The proxy sends messages across the network to

a “skeleton” object The skeleton calls the subject object.

Page 5: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 5

One Remote Method Call.

(0) Client calls stub

(1) Stub messages skeleton

(2) Skeleton calls server (subject)

(3) Call returns

(4) Skeleton messages proxy

(5) Call returns

Client

Stub(Proxy)

Server

Skeleton

(1)

(0)(2) (3)

(4)

(5)

Call

Return

Message

Network

Object

Process(JVM)

Page 6: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 6

Full disclosure The term “skeleton object” is out of date. The point

is that some code (that you don’t have to write) running on the server’s jvm will turn network traffic into method calls to the server object and method returns (or exceptions) into network traffic.

I’ll continue to use the term “skeleton object” to refer to the object(s) that perform these duties.

Page 7: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 7

Issues Concurrency

If there are multiple clients, the server may field multiple calls at the same time. So use synchronization as appropriate.

Argument passing Arguments are passed by value or “by proxy” not by

reference. Proxy generation

Proxy classes are automatically derived from the server class’s interface.

Lookup Objects are usually found via a registry (program

rmiregistry)

Page 8: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 8

Nitty-Gritty The proxy and the server share an interface.

This interface must extend java.rmi.Remote. Every method in the interface should be declared to throw

java.rmi.RemoteException RemoteExceptions are thrown when network problems are

encountered, or when server objects no longer exist.

The server typically extends class java.rmi.server.UnicastRemoteObject The constructor of this class throws a RemoteException Therefore, so should the constructor of any specialization.

Page 9: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 9

Argument Passing Revisited Most arguments and results

are converted to a sequence of bytes; the bytes are sent over the net therefore the class should implement the

java.io.Serializable interface a clone of the argument/result is constructed on the other

side. The effect is pass by object value, rather than by object

reference. But

objects that extend java.rmi.server.RemoteObject instead have a proxy constructed for them on the other side I call this “pass by proxy”. Essentially pass by reference

So each argument, result, exception type should be a primitive type, Serializable, or extend RemoteObject

Page 10: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 10

An Example – Distributed Othello Othello is a two person board game My implementation uses the observer pattern

so that, when the (game state) model changes, all observers are informed of the change.

I wanted to put the model on one machine and the observers on other machines.

Hence I implemented the observer pattern with RMI.

This is example othello-2 on the website.

Page 11: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 11

The Observer Pattern

Subject alerts Observers of changes of state.

Page 12: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 12

Observer Pattern

Page 13: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 13

Object diagram for Othello 2

:BoardView

:Animator

: BoardView

:Animator

:RemoteGameModel

Client Host 0 Client Host 1

Server Host

Observes Observes

ObservesObserves

Notifies Notifies

Notifies Notifies

Page 14: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 14

… with proxies and skeletons: BoardView

:Animator

:RemoteGameModel

Observes

Skeleton

Animator Proxy

Skeleton

Remote Game Model’s Proxy

Observes

Communicateswith

Communicates with

Notifies

Server Host

Notifies

Animator Proxy

: BoardView

:Animator

Observes Skeleton

Remote Game Model’s Proxy

Observes

Communicateswith

Communicateswith

Notifies

Notifies

Notifies

ClientHost

Another Client Host

Page 15: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 15

The Observer Pattern for Othello

Page 16: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 16

Proxy for the Remote Game Model

Page 17: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 17

Proxies for the Animators

Page 18: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 18

Animator / RemoteGameModel Relationship

Page 19: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 19

Typical sequence —slightly simplified A remote client calls a synchronized mutator on the

RemoteGameModel via its stub & skeleton The RemoteGameModel updates its state and notifies each

Animator via its stubs & skeletons. The Observers (Animator objects) call the

RemoteGameModel accessor “getPieceAt” via its stubs and skeleton.

(Therefore this accessor must not be synchronized!) getPieceAt returns

The update routines return. The original mutator call returns and the

RemoteGameModel becomes unlocked.

Page 20: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 20

Typical sequence —slightly simplifiedsomeObj : RemoteGameModel : RemoteGameModel_Stub : Animator_Stub : Animator

move(int, int, int)

notifyObservers(...)

update(...)

update(...)

Across net with help of skeleton

getPieceAt(int, int)

getPieceAt(int, int)

Across net with help of skeleton

Calls to other accessors are similar

Page 21: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 21

Concurrent Notification The previous sequence is slightly simplified.

In fact the Animators return from update immediately (so that all can be informed essentially at the same time). The Animation threads will inform the

RemoteGameModel of when they have completed their animation.

The RemoteGameModel waits until it has been informed that all animations are complete. The effect is that the animations can happen

concurrently, yet the RemoteGameModel does not unlock until all animations are complete and all models agree on the board state.

See RemotelyConcurrentlyObservable for details.

Page 22: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 22

Concurrent Notification

I simplifed this diagram a bit by omitting the callbacks from the animators to the game model and by omitting the stubs and skeletons.

During this time the animators animate (using new threads created in update). The last thing these threads do is call decrement (via RMI). Once all the animation threads have called decrement, the original server thread returns from waitForZero

someObj : RemoteGameModel : RemoteCountMonitor : Animator : Animator

move(...)

notifyObservers(...)

update(...)

update(...)

waitForZero( )

decrement( )

decrement( )

Page 23: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 23

Naming the Server Normally an object’s address serves as a unique

identifier But this only makes sense in the context of a given JVM

process. We would like objects to have unique identifiers that are

unique in the world. The rmiregistry allows you to give a URI to an object And to obtain a proxy for an object that has a URI. URIs are: rmi://host/name The host must be running a rmiregistry process and that

process should have the appropriate class files on its CLASSPATH

Page 24: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 24

Binding the server to a name.

The main routine for the server The static method bind in Naming gives a URI to

gameModelpublic static void main( String[] args ) { try { RemoteGameModel gameModel = new RemoteGameModel(); String name = args[0] ; Naming.bind( name, gameModel ) ; System.err.println("Game model bound to "+name);} catch( java.net.MalformedURLException e) { … } catch( AlreadyBoundException e) { … } catch( RemoteException e ) { … } }

Page 25: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 25

Bind

i.jar

Webserver

java -Djava.rmi.server.codebase=U -cp s.jar ServerMainClass

bind

get

U is the URL of i.jar

gm

GameModel object

Proxy objects

Skeleton object

read

i.jar only needs the class filesfor the server object’s interface.

RMIRegistry

JVMs

Animator object

1. A call Naming.bind(uri,gm) is made.

1.1 A proxy object is created. 1.1.1 A serialization of the proxy is sent to the registry.

1.1.1.1 A copy is created in the registry’s vm.

The uri specifies the host (and port) of theRMI registry process.

Page 26: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 26

Looking up the server object

The clients obtain a proxy for the game model using Naming.lookup( URI )

From ClientMain.javapublic static void main( String[] args) {

RemoteGameModelInterface proxy = null ;

try {

String name = args[0] ;

proxy = (RemoteGameModelInterface)

Naming.lookup( name ) ; }

catch( java.net.MalformedURLException e) { … }

catch( NotBoundException e) { … }

catch( RemoteException e) { … }

… continued on the slide after next …

Page 27: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 27

Looking up the server object

java -Djava.rmi.server.codebase=U -cp s.jar ServerMainClass

java -cp c.jar ClientMainClass

lookup(uri)

GameModel object

Proxy objects

Skeleton object

RMIRegistry

JVMs

Animator object

2. Naming.lookup(uri) is called on the client vm.

2.1 A lookup message is sent to the RMI registry.

2.1.1. A serialized copy of the proxy is sent to the client. And a proxy is built in the client vm.

Page 28: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 28

Closing the loop The client then can use the proxy. E.g.

Continuing the ClientMain main routine…Animator animator0 = null ;try { animator0 = new Animator( proxy ) ; }catch( RemoteException e ) { … }

The constructor for Animatorpublic Animator( RemoteGameModelInterface gameModel )throws RemoteException { super() ; … gameModel.addObserver(this); }

Page 29: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 29

Adding a remote Observer.

Each Animator calls addObserver(this) on the RemoteGameModel’s proxy. Since Animator implements RemoteObject, it is

passed by proxy, meaning a proxy for the Animator is constructed in the JVM

of the RemoteGameModel. (see next slide.)

Page 30: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 30

Adding a remote observer

gm

GameModel object

Proxy objects

Skeleton objects

JVMs

Animator objectani

gmp

addObserver(a)

addObserver( )

addObserver(anip)

anip

3 the animator (ani) calls addObserver(this) on the game model’s proxy (gmp)

3.1 the client vm sends a serialized proxy for ani to the server vm.

3.1.1 The animator’s proxy (anip) is constructed in the server vm.

3.1.1.1 An addObserver(anip) message is sent to the game model, which saves anip’s address to its observer list.

Page 31: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 31

The final hookup (again)

:Animator

:RemoteGameModel

Client Host 0

Observes

Skeleton Animator Proxy

Skeleton

Remote Game Model’s Proxy

Communicates with

Communicates with

Notifies

Server Host

Calls

Calls

Page 32: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 32

Creating the stubs and skeletons First we write a server class: E.g.

public class RemoteGameModel

extends RemotelyConcurrentlyObservable

implements RemoteGameModelInterface

{

public RemoteGameModel() throws RemoteException {

super() ; } … }

We compile it with “javac” The stub objects will be created automatically at

run time.

Page 33: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 33

Starting an RMI registry In order to build a proxy object, the RMIRegistry

process needs access to the .class file(s) for the interface.

Option 0. Run the RMIRegistry with the appropriate .class files on its classpath.

Option 1. Put the class files on a webserver and, when the server is run, use the following option -Djava.rmi.server.codebase=URL

(Option 1 was illustrated earlier in the animation of the bind process.)

Page 34: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 34

A Few Words of Warning

RMI makes it seductively easy to treat remote objects as if they were local.

Keep in mind Partial Failure

Part of the system of objects may fail Partial failures may be intermittent Network delays On a large network, delays are indistinguishable from

failures In the Othello example, failure was not considered. The

system is not designed to be resilient to partial failures.

Page 35: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 35

A Few Words of Warning (cont.) Keep in mind (cont.)

Performance Remote calls are several orders of magnitude more expensive

than local calls (100,000 or more to 1) E.g. in the Othello example, this motivated splitting the model into

local (Animator) and remote (RemoteGameModel) copies. Concurrency

Remote calls introduce concurrency that may not be in a nondistributed system. E.g. in Othello, I had to be careful not to use synchronized for

accessors called by remote Observers and to consider the data integrity consequences of not doing so. (The reason was that the call to the mutator and the call to the accessor are in different threads each spun off the skeleton. Therefore the call to the mutator would lock out the call to the accessor, if both were synchronized.)

Page 36: 1 Remote Method Invocation (RMI) and Distributed Observers in Java Theodore Norvell.

© 2004-10 T. S. NorvellEngineering 5895 Memorial

University RMI. Slide 36

A Few Words of Warning (cont.) Keep in mind (cont.)

Semantics changes In Java, local calls pass objects by pointer value. Remote calls pass objects either by copy or by copying

a proxy. E.g. in the Othello game as I converted from the

nondistributed to a distributed version, the semantics of some calls changed, even though I did not change the source code for those calls.