The Net Worth of an Object-Oriented Pattern

Slides:



Advertisements
Similar presentations
COS 461 Fall 1997 Network Objects u first good implementation: DEC SRC Network Objects for Modula-3 u recent implementation: Java RMI (Remote Method Invocation)
Advertisements

Designing an ADT The design of an ADT should evolve naturally during the problem-solving process Questions to ask when designing an ADT What data does.
Copyright © 2001 Qusay H. Mahmoud RMI – Remote Method Invocation Introduction What is RMI? RMI System Architecture How does RMI work? Distributed Garbage.
15-May-15 RMI Remote Method Invocation. 2 “The network is the computer” Consider the following program organization: If the network is the computer, we.
Advanced Programming Rabie A. Ramadan Lecture 4. A Simple Use of Java Remote Method Invocation (RMI) 2.
Remote Method Invocation
Remote Object Invocation Tran, Van Hoai Department of Systems & Networking Faculty of Computer Science & Engineering HCMC University of Technology.
Road Map Introduction to object oriented programming. Classes
Remote Method Invocation Chin-Chih Chang. Java Remote Object Invocation In Java, the object is serialized before being passed as a parameter to an RMI.
EEC-681/781 Distributed Computing Systems Lecture 5 Wenbing Zhao Department of Electrical and Computer Engineering Cleveland State University
CSE331: Introduction to Networks and Security Lecture 11 Fall 2002.
CS220 Software Development Lecture: Multi-threading A. O’Riordan, 2009.
Introduction to Remote Method Invocation (RMI)
How Does Remote Method Invocation Work? –Systems that use RMI for communication typically are divided into two categories: clients and servers. A server.
Terms and Rules Professor Evan Korth New York University (All rights reserved)
Lesson 3 Remote Method Invocation (RMI) Mixing RMI and sockets Rethinking out tic-tac-toe game.
Week 4-5 Java Programming. Loops What is a loop? Loop is code that repeats itself a certain number of times There are two types of loops: For loop Used.
REFACTORING Lecture 4. Definition Refactoring is a process of changing the internal structure of the program, not affecting its external behavior and.
1 Java Programming II Java Network II (Distributed Objects in Java)
Architecture of Software Systems RMI and Distributed Components Martin Rehák.
Netprog: Java Intro1 Crash Course in Java. Netprog: Java Intro2 Why Java? Network Programming in Java is very different than in C/C++ –much more language.
In the name of Allah The Proxy Pattern Elham moazzen.
1 Java RMI G53ACC Chris Greenhalgh. 2 Contents l Java RMI overview l A Java RMI example –Overview –Walk-through l Implementation notes –Argument passing.
Spring/2002 Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads 1 RMI.
Li Tak Sing COMPS311F. Case study: consumers and producers A fixed size buffer which can hold at most certain integers. A number of producers which generate.
RMI remote method invocation. Traditional network programming The client program sends data to the server in some intermediary format and the server has.
RMI Remote Method Invocation Distributed Object-based System and RPC Together 2-Jun-16.
 Remote Method Invocation  A true distributed computing application interface for Java, written to provide easy access to objects existing on remote.
The Net Worth of an Object-Oriented Pattern Practical Implications of the Java RMI Adrian German Lecturer, Computer Science Department Indiana University.
Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to.
RMI Observing the Distributed Pattern. Adrian German Lecturer, Computer Science Indiana University Bloomington.
Remote Method Invocation A Client Server Approach.
UMBC Distributed Computing with Objects RMI/Corba CMSC 432 Shon Vick.
1 Lecture 15 Remote Method Invocation Instructors: Fu-Chiung Cheng ( 鄭福炯 ) Associate Professor Computer Science & Engineering Tatung Institute of Technology.
Netprog Java RMI1 Remote Method Invocation.
Distributed Web Systems Distributed Objects and Remote Method Invocation Lecturer Department University.
Remote Procedure Calls
CMSC202 Computer Science II for Majors Lecture 16 – Exceptions
Principles of Software Development
Chapter 1 Introduction to Computers, Programs, and Java
Java Remote Method Invocation (RMI)
Broker in practice: Middleware
Remote Method Invocation
What is RMI? Remote Method Invocation
Remote Method Invocation
CS360 Windows Programming
Fall 2017 CISC124 9/21/2018 CISC124 First onQ quiz this week – write in lab. More details in last Wednesday’s lecture. Repeated: The quiz availability.
Programming Models for Distributed Application
Java Programming Language
Lecture 4: RPC Remote Procedure Call Coulouris et al: Chapter 5
CSE 451: Operating Systems Autumn 2003 Lecture 16 RPC
Chapter 40 Remote Method Invocation
Lecture 4: RPC Remote Procedure Call CDK: Chapter 5
Units with – James tedder
Units with – James tedder
SAMANVITHA RAMAYANAM 18TH FEBRUARY 2010 CPE 691
CSE 451: Operating Systems Autumn 2009 Module 21 Remote Procedure Call (RPC) Ed Lazowska Allen Center
Distribution Infrastructures
Chapter 46 Remote Method Invocation
Chapter 46 Remote Method Invocation
CS 584 Lecture 18 Assignment Glenda assignment extended to the Java RMI Deadline No Java RMI Assignment Test Friday, Saturday, Monday.
CSE 451: Operating Systems Autumn 2010 Module 21 Remote Procedure Call (RPC) Ed Lazowska Allen Center
Java Remote Method Invocation
Software Design Lecture : 38.
CSE 451: Operating Systems Winter 2003 Lecture 16 RPC
CMPE212 – Reminders Assignment 2 due next Friday.
Last Class: Communication in Distributed Systems
CSE 451: Operating Systems Messaging and Remote Procedure Call (RPC)
Exceptions and networking
Java Chapter 5 (Estifanos Tilahun Mihret--Tech with Estif)
Presentation transcript:

The Net Worth of an Object-Oriented Pattern Practical Implications of the Java RMI Adrian German Lecturer, Computer Science Department Indiana University Bloomington

There will be a server, implemented as follows: class ServerImplementation { }

There will be many clients, implemented as follows: class ClientImplementation { }

The server has a business card: public interface Server { }

And it implements it: class ServerImplementation implements Server { }

The client also has a business card: public interface Client { }

And, like the server, it makes a promise to fulfill it: class ClientImplementation implements Client { }

The server keeps track of clients: class ServerImplementation implements Server { Client[] clients = new Client[100]; int index = -1; }

The server keeps track of clients: class ServerImplementation implements Server { Client[] clients = new Client[100]; int index = -1; } The index of the most recently allocated cell is -1 if the array is empty.

The server keeps track of clients: class ServerImplementation implements Server { Client[] clients = new Client[100]; int index = -1; } The index of the most recently allocated cell is -1 if the array is empty. Note that: • the server calls the clients by using the title (type) printed on their business cards

The server keeps track of clients: class ServerImplementation implements Server { Client[] clients = new Client[100]; int index = -1; } The index of the most recently allocated cell is -1 if the array is empty. Note that: • the server calls the clients by using the title (type) printed on their business cards • plain arrays are used as instance variables to just make the type(s) more explicit

What else does the server do?

What else does the server do? public interface Server { public void register(Client client); }

What else does the server do? public interface Server { public void register(Client client); } It allows clients to register with it, whatever that means.

Although that, in this case, amounts to: synchronized public void register(Client client) { clients[++this.index] = client; client.setID(new Integer(this.index)); for (int i = 0; i < this.index; i++) { clients[i].register(new Integer(this.index), client); client.register(new Integer(i), clients[i]); }

Although that, in this case, amounts to: synchronized public void register(Client client) { clients[++this.index] = client; client.setID(new Integer(this.index)); for (int i = 0; i < this.index; i++) { clients[i].register(new Integer(this.index), client); client.register(new Integer(i), clients[i]); } So we see that, apparently, a client: • can set its ID (through/during registration with the server,)

Although that, in this case, amounts to: synchronized public void register(Client client) { clients[++this.index] = client; client.setID(new Integer(this.index)); for (int i = 0; i < this.index; i++) { clients[i].register(new Integer(this.index), client); client.register(new Integer(i), clients[i]); } So we see that, apparently, a client: • can set its ID (through/during registration with the server,) and • allows any other client to register with it (also through/by the server)

This changes the client business card a little: (that the server knows) public interface Client { public void setID(Integer index); public void register(Integer index, Client client); }

This changes the client business card a little: (that the server knows) public interface Client { public void setID(Integer index); public void register(Integer index, Client client); } Let’s see how these promises can be fulfiled.

First off, every client will have an own numeric id: class ClientImplementation implements Client { int id; synchronized public void setID (Integer index) { this.id = index.intValue(); }

Secondly, the world (collection) of peers initially registered with the server is replicated in each client: class ClientImplementation implements Client { int id; synchronized public void setID (Integer index) { this.id = index.intValue(); } Client[] peer = new Client[100]; int index = -1; synchronized public void register(Integer index, Client client) { this.index = index.intValue(); this.peer[this.index] = client;

Secondly, the world (collection) of peers initially registered with the server is replicated in each client: class ClientImplementation implements Client { int id; synchronized public void setID (Integer index) { this.id = index.intValue(); } Client[] peer = new Client[100]; int index = -1; synchronized public void register(Integer index, Client client) { this.index = index.intValue(); this.peer[this.index] = client;

Let’s go back to the server.

Let’s go back to the server. How does it get started and what does it do?

Let’s go back to the server. How does it get started and what does it do? The server has no constructor.

Let’s go back to the server. How does it get started and what does it do? The server has no constructor. The server is implemented as a thread.

In its run() method the server constantly broadcasts to clients: class ServerImplementation implements Server, Runnable { ... public void run() { while (true) { try { Thread.sleep((int)(Math.random() * 5000 + 5000)); this.broadcast(); } catch (Exception e) { } }

Broadcasting amounts to the following: synchronized public void broadcast() { for (int i = 0; i <= this.index; i++) clients[i].setAvailable(new Boolean(false)); for (int i = 0, check = 0; i <= this.index; i++) check += clients[i].getBalance(); clients[i].setAvailable(new Boolean(true)); }

Broadcasting amounts to the following: synchronized public void broadcast() { for (int i = 0; i <= this.index; i++) clients[i].setAvailable(new Boolean(false)); for (int i = 0, check = 0; i <= this.index; i++) check += clients[i].getBalance(); clients[i].setAvailable(new Boolean(true)); }

Broadcasting amounts to the following: synchronized public void broadcast() { for (int i = 0; i <= this.index; i++) clients[i].setAvailable(new Boolean(false)); for (int i = 0, check = 0; i <= this.index; i++) check += clients[i].getBalance(); clients[i].setAvailable(new Boolean(true)); }

During broadcasting:

During broadcasting: clients are first shut down (by setting their availability to false)

During broadcasting: clients are first shut down (by setting their availability to false) the sum of points for the entire collection of clients is calculated

During broadcasting: clients are first shut down (by setting their availability to false) the sum of points for the entire collection of clients is calculated and clients are then turned back on, one by one

During broadcasting: clients are first shut down (by setting their availability to false) the sum of points for the entire collection of clients is calculated and clients are then turned back on, one by one Here’s how we accomplish these steps.

Setting the availability and returning the current balance are advertised by the clients. public interface Client { public void register(Client client); public void setID(Integer index); public void setAvailable(Boolean availability); public int getBalance(); }

public interface Client { public void register(Client client); Setting the availability and returning the current balance are advertised by the clients. public interface Client { public void register(Client client); public void setID(Integer index); public void setAvailable(Boolean availability); public int getBalance(); } The implementation of these two functions is immediate.

Boolean available = new Boolean(true); synchronized public void setAvailable(Boolean availability) { this.available = availability; } int balance; public int getBalance() { return this.balance;

Boolean available = new Boolean(true); synchronized public void setAvailable(Boolean availability) { this.available = availability; } int balance; public int getBalance() { return this.balance; What else does the server do?

Broadcasting is just a little bit more complicated but other than that, that’s it. // after turning the clients off String report = “”, calculation=“”; int check = 0; for (int i = 0; i <= this.index; i++) { report += clients[i].report() + "\n"; calculation += "(" + clients[i].getBalance() + ").."; check += clients[i].getBalance(); } System.out.println("Server sees: " + report); System.out.println(calculation + " ---> " + check); // now turn the clients back on

Clients need to provide the added level of functionality: public interface Client { public void setID(Integer index); public void register(Integer index, Client client); public void setAvailable(Boolean availability); public int getBalance(); public String report(); }

Implementation for this extra feature is immediate, as well: class ClientImplementation implements Client { ... String name; public String report() { return this.name + ": " + this.balance; }

Implementation for this extra feature is immediate, as well: class ClientImplementation implements Client { ... String name; public String report() { return this.name + ": " + this.balance; } How does one start the server?

The server provides a method for that: class ServerImplementation implements Server, Runnable { ... public void startAsLocalServer() { new Thread(this).start(); }

If we were to try this program out we'd do something like this: class LocalSetup { public static void main(String[] args) { }

A server needs to be created, then started: class LocalSetup { public static void main(String[] args) { ServerImplementation server = new ServerImplementation(); server.startAsLocalServer(); }

A server needs to be created, then started: class LocalSetup { public static void main(String[] args) { ServerImplementation server = new ServerImplementation(); server.startAsLocalServer(); } We need some clients, too.

A server needs to be created, then started: class LocalSetup { public static void main(String[] args) { ServerImplementation server = new ServerImplementation(); server.startAsLocalServer(); } We need some clients, too. But how does one create a client?

class ClientImplementation implements Client { ... public ClientImplementation(String name) { this.name = name; } We need some clients, too. But how does one create a client?

So we can create a few clients now: class LocalSetup { public static void main(String[] args) { ServerImplementation server = new ServerImplementation(); server.startAsLocalServer(); for (int i = 0; i < 6; i++) { ClientImplementation dealer = new ClientImplementation("Dealer_" + i); dealer.startAsClientOf(server); }

And, if started, what do clients do? class ClientImplementation implements Client { ... public void startAsClientOf(java.rmi.Remote peer) { Server server = (Server) peer; server.register(this); this.server = server; new Thread(this).start(); } Server server;

class ClientImplementation implements Client { ... public void startAsClientOf(java.rmi.Remote peer) { Server server = (Server) peer; server.register(this); this.server = server; new Thread(this).start(); } Server server;

class ClientImplementation implements Client { ... public void startAsClientOf(java.rmi.Remote peer) { Server server = (Server) peer; server.register(this); this.server = server; new Thread(this).start(); } Server server; In describing how we start the clients we acknowledge for the first time the distributed nature of our goal.

And, if started, what do clients do? This addition however has significant ramifications. And, if started, what do clients do?

And, if started, what do clients do? This addition however has significant ramifications. And, if started, what do clients do? public interface Server extends java.rmi.Remote { public void register(Client client); } First, the server needs to match the type.

class ClientImplementation implements Client, Runnable { ... In addition to that clients need to be described in their active behaviour. class ClientImplementation implements Client, Runnable { ... public void run() { while (true) { try { Thread.sleep((int)(Math.random() * 1000 + 1000)); if (this.available.booleanValue()) this.initiateTransfer(); } catch (Exception e) { } }

class ClientImplementation implements Client, Runnable { ... In addition to that clients need to be described in their active behaviour. class ClientImplementation implements Client, Runnable { ... public void run() { while (true) { try { Thread.sleep((int)(Math.random() * 1000 + 1000)); if (this.available.booleanValue()) this.initiateTransfer(); } catch (Exception e) { } } So that's what clients typically do: wait, then initiate a transfer.

class ClientImplementation implements Client, Runnable { ... Initiating a transfer has the following description: class ClientImplementation implements Client, Runnable { ... synchronized private void initiateTransfer() { if (this.index > 0) { int chosen = (int) (Math.random() * (this.index + 1)); if (chosen == this.id // always deal with someone else || peer[chosen] == null) return; this.balance += peer[chosen].process( new Transaction(this.name, this.id, (int) (Math.random() * 10 + 1), Math.random() > 0.5 ? "sent" : "requested")); }

class ClientImplementation implements Client, Runnable { ... Initiating a transfer has the following description: class ClientImplementation implements Client, Runnable { ... synchronized private void initiateTransfer() { if (this.index > 0) { int chosen = (int) (Math.random() * (this.index + 1)); if (chosen == this.id // always deal with someone else || peer[chosen] == null) return; this.balance += peer[chosen].process( new Transaction(this.name, this.id, (int) (Math.random() * 10 + 1), Math.random() > 0.5 ? "sent" : "requested")); }

public class Transaction { String initiatorName; int initiatorID; A description of process() and Transaction follows: public class Transaction { String initiatorName; int initiatorID; int amount; String direction; public Transaction(String name, int id, int amount, String direction) { this.initiatorName = name; this.id = id; this.amount = amount; this.direction = direction; }

public class Transaction { String initiatorName; int initiatorID; A description of process() and Transaction follows: public class Transaction { String initiatorName; int initiatorID; int amount; String direction; public Transaction(String name, int id, int amount, String direction) { this.initiatorName = name; this.id = id; this.amount = amount; this.direction = direction; } Transactions are passive, but they could easily be turned into visitors.

class ClientImplementation implements ... { ... Processing is not very complicated: class ClientImplementation implements ... { ... synchronized public int process(Transaction trans) { if (this.available.booleanValue()) if (trans.direction.equals("sent")) { this.balance += trans.amount; return - (trans.amount); } else { this.balance -= trans.amount; return (trans.amount); } else return 0; // object unavailable: method idempotent

public interface Client { ... And process() must be added to a Client's business card: public interface Client { ... public int process(Transaction transaction); } So our application has been developed now.

public interface Client { ... And process() must be added to a Client's business card: public interface Client { ... public int process(Transaction transaction); } So our application has been developed now. One can run LocalSetup to test it.

Is it possible to have avoided using java.rmi.Remote at all?

Is it possible to have avoided using java.rmi.Remote at all? Perhaps so, but this approach is a bit more general, since we could have more than one kind of server.

public void startAsClientOf(java.rmi.Remote peer) { Is it possible to have avoided using java.rmi.Remote at all? Perhaps so, but this approach is a bit more general, since we could have more than one kind of server. That is, we could easily rewrite startAsClientOf as follows: public void startAsClientOf(java.rmi.Remote peer) { if (peer instanceof Server) { // the code we have thus far } else { // throw an exception or do something else }

public void startAsClientOf(java.rmi.Remote peer) { Is it possible to have avoided using java.rmi.Remote at all? Perhaps so, but this approach is a bit more general, since we could have more than one kind of server. That is, we could easily rewrite startAsClientOf as follows: public void startAsClientOf(java.rmi.Remote peer) { if (peer instanceof Server) { // the code we have thus far } else { // throw an exception or something } Now we will show how we distribute the program without touching the application logic developed thus far.

Let's introduce this abstraction: public abstract class NetworkPeer implements java.rmi.Remote { }

It provides tools for creating proxies used for remote access: public abstract class NetworkPeer implements java.rmi.Remote { public void exportMethods() throws java.rmi.RemoteException { java.rmi.server.UnicastRemoteObject.exportObject(this); }

It provides the ability to locate a peer server (by its external address): public abstract class NetworkPeer implements java.rmi.Remote { ... public java.rmi.Remote locatePeer(String peerHost, int peerPort, String peerName) throws Exception { return java.rmi.Naming.lookup( "rmi://" + peerHost + ":" + peerPort + "/" + peerName ); }

It provides a standard/default definition of startAsNetworkClient() public abstract class NetworkPeer implements java.rmi.Remote { ... public void startAsNetworkClient(String peerHost, int peerPort, String peerName) throws Exception { this.exportMethods(); java.rmi.Remote peer = this.locatePeer(peerHost, peerPort, peerName); this.startAsClientOf(peer); // see below ... }

It provides a standard/default definition of startAsNetworkClient() public abstract class NetworkPeer implements java.rmi.Remote { ... public void startAsNetworkClient(...) throws Exception { this.startAsClientOf(peer); // see below ... } public abstract void startAsClientOf(java.rmi.Remote peer) throws java.rmi.RemoteException;

It provides a standard/default definition of startAsNetworkServer() public abstract class NetworkPeer implements java.rmi.Remote { ... public void startAsNetworkServer(String name, int port) { System.setSecurityManager(new java.rmi.RMISecurityManager()); try { this.exportMethods(); java.rmi.registry.Registry registry = java.rmi.registry.LocateRegistry.createRegistry(port); registry.bind(name, this); this.startAsLocalServer(); // see below ... System.out.println("Server is ready ... "); } catch (Exception e) { System.out.println("Server error: " + e + " ... "); } public abstract void startAsLocalServer(); // startAsServer?

This abstraction encapsulates and provides everything needed. public abstract class NetworkPeer implements java.rmi.Remote { ... public void startAsNetworkServer(String name, int port) { System.setSecurityManager(new java.rmi.RMISecurityManager()); try { this.exportMethods(); java.rmi.registry.Registry registry = java.rmi.registry.LocateRegistry.createRegistry(port); registry.bind(name, this); this.startAsLocalServer(); // see below ... System.out.println("Server is ready ... "); } catch (Exception e) { System.out.println("Server error: " + e + " ... "); } public abstract void startAsLocalServer(); // startAsServer?

First for the server: class ServerImplementation extends NetworkPeer implements Server, Runnable { ... public static void main(String[] args) { String portNumber = args[0], ownName = args[1]; ServerImplementation here = new ServerImplementation(); here.startAsNetworkServer(ownName, Integer.parseInt(portNumber)); // startAsLocalServer called in the process ... } public void startAsClientOf(java.rmi.Remote peer) { // empty, server is a peer with a public address

And then for the client: class ClientImplementation extends NetworkPeer implements Client, Runnable { ... public static void main(String[] args) throws Exception { String ownName = args[0], serverHostName = args[1], serverPortNumber = args[2], serverName = args[3]; ClientImplementation client = new ClientImplementation(name); client.startAsNetworkClientOf(serverHostName, Integer.parseInt(serverPortNumber), serverName); // startAsClientOf will be called in the process ... } public void startAsLocalServer() { // a client is a peer/guest without a permanent address ...

And there's one last change we need to make: public class Transaction implements java.io.Serializable { // everything else exactly the same }

However, additional decoration will be required for networking: class ServerImplementation extends ... implements ..., java.rmi.Remote { ... ... void register(...) throws java.rmi.RemoteException { ... } } public interface Server extends java.rmi.Remote { public void register(...) throws java.rmi.RemoteException; class ClientImplementation extends ... implements ... { ... void startAsClientOf(...) throws java.rmi.RemoteException { ... } class LocalSetup { public static void main(String[] args) throws /*java.rmi.Remote*/Exception { ... }

And we need to take care of the ClientImplementation as well: public interface Client extends java.rmi.Remote { public void setID(...) throws java.rmi.RemoteException; public void register(...) throws java.rmi.RemoteException; public void setAvailable(...) throws java.rmi.RemoteException; public int getBalance() throws java.rmi.RemoteException; public String report() throws java.rmi.RemoteException; public int process(...) throws java.rmi.RemoteException; } class ClientImplementation extends ... implements ... { ... public void setID(...) throws java.rmi.RemoteException { ... }; public void register(...) throws java.rmi.RemoteException { ... }; public void setAvailable(...) throws java.rmi.RemoteException { ... }; public int getBalance() throws java.rmi.RemoteException { ... }; public String report() throws java.rmi.RemoteException { ... }; public int process(...) throws java.rmi.RemoteException { ... };

And the decorations propagate one last step: class ServerImplementation extends ... implements ... { ... synchronized public void broadcast() throws java.rmi.RemoteException { ... } }

And the decorations propagate one last step: class ServerImplementation extends ... implements ... { ... synchronized public void broadcast() throws java.rmi.RemoteException { ... } } So, as we can see, the code we developed originally has not been touched, and is being used unchanged.

Now we can start the programs in distributed fashion: tucotuco% javac *.java tucotuco% rmic ServerImplementation tucotuco% rmic ClientIimplementation tucotuco% java ServerImplementation 36091 theServer Server is ready... In this example the server is started on tucotuco.cs.indiana.edu as theServer on port 36091. The clients will be started on molerat, burrowww, blesmol, and bobac, when they are ready to join. These are different machines that share the filespace through NFS so one doesn't need to worry about distributing (deploying) the code around. But the machines have distinct network identity so when we start the programs they are loaded in distinct locations of the network as well.

Now we can start the programs in distributed fashion: tucotuco% javac *.java tucotuco% rmic ServerImplementation tucotuco% rmic ClientIimplementation tucotuco% java ServerImplementation 36091 theServer Server is ready... In this example the server is started on tucotuco.cs.indiana.edu as theServer on port 36091. The clients will be started on molerat, burrowww, blesmol, and bobac, when they are ready to join. These are different machines that share the filespace through NFS so one doesn't need to worry about distributing (deploying) the code around. But the machines have distinct network identity so when we start the programs they are loaded in distinct locations of the network as well.

Now we can start the programs in distributed fashion: tucotuco% javac *.java tucotuco% rmic ServerImplementation tucotuco% rmic ClientIimplementation tucotuco% java ServerImplementation 36091 theServer Server is ready... In this example the server is started on tucotuco.cs.indiana.edu as theServer on port 36091. The clients will be started on molerat, burrowww, blesmol, and bobac, when they are ready to join. These are different machines that share the filespace through NFS so one doesn't need to worry about distributing (deploying) the code around. But the machines have distinct network identity so when we start the programs they are loaded in distinct locations of the network as well.

Now we can start the programs in distributed fashion: tucotuco% javac *.java tucotuco% rmic ServerImplementation tucotuco% rmic ClientIimplementation tucotuco% java ServerImplementation 36091 theServer Server is ready... In this example the server is started on tucotuco.cs.indiana.edu as theServer on port 36091. The clients will be started on molerat, burrowww, blesmol, and bobac, when they are ready to join. These are different machines that share the filespace through NFS so one doesn't need to worry about distributing (deploying) the code around. But the machines have distinct network identity so when we start the programs they are loaded in distinct locations of the network as well.

So here's how we start the clients: burrowww% java ClientImplementation larry tucotuco.cs.indiana.edu 36091 theServer

So here's how we start the clients: burrowww% java ClientImplementation larry tucotuco.cs.indiana.edu 36091 theServer blesmol% java ClientImplementation michael tucotuco.cs.indiana.edu 36091 theServer

So here's how we start the clients: burrowww% java ClientImplementation larry tucotuco.cs.indiana.edu 36091 theServer blesmol% java ClientImplementation michael tucotuco.cs.indiana.edu 36091 theServer bobac% java ClientImplementation toni tucotuco.cs.indiana.edu 36091 theServer

So here's how we start the clients: burrowww% java ClientImplementation larry tucotuco.cs.indiana.edu 36091 theServer blesmol% java ClientImplementation michael tucotuco.cs.indiana.edu 36091 theServer bobac% java ClientImplementation toni tucotuco.cs.indiana.edu 36091 theServer molerat% java ClientImplementation richard tucotuco.cs.indiana.edu 36091 theServer

And the LocalSetup still works as before.

And the LocalSetup still works as before. So one can (and should) use this pattern from the outset.

Object-oriented programming is really about distributed programming.

Object-oriented programming is really about distributed programming. And it appears to have been like this from the beginning: "In 1961 [Alan] Kay worked on the problem of transporting data files and procedures from one Air Force air training installation to another and discovered that some unknown programmer had figured out a clever method of doing the job. The idea was to send the data bundled along with its procedures, so that the program at the new installation could use the procedures directly, even without knowing the format of the data files. The procedures themselves could find the information they needed from the data files. The idea that a program could use procedures without knowing how the data was represented struck Kay as a good one. It formed the basis for his later ideas about objects." (Dennis Shasha, Cathy Lazere, Out of Their Minds [...], Copernicus, Springer Verlag 1995)

Object-oriented programming is really about distributed programming. And it appears to have been like this from the beginning: "In 1961 [Alan] Kay worked on the problem of transporting data files and procedures from one Air Force air training installation to another and discovered that some unknown programmer had figured out a clever method of doing the job. The idea was to send the data bundled along with its procedures, so that the program at the new installation could use the procedures directly, even without knowing the format of the data files. The procedures themselves could find the information they needed from the data files. The idea that a program could use procedures without knowing how the data was represented struck Kay as a good one. It formed the basis for his later ideas about objects." (Dennis Shasha, Cathy Lazere, Out of Their Minds [...], Copernicus, Springer Verlag 1995)

Object-oriented programming is really about distributed programming. And it appears to have been like this from the beginning: "In 1961 [Alan] Kay worked on the problem of transporting data files and procedures from one Air Force air training installation to another and discovered that some unknown programmer had figured out a clever method of doing the job. The idea was to send the data bundled along with its procedures, so that the program at the new installation could use the procedures directly, even without knowing the format of the data files. The procedures themselves could find the information they needed from the data files. The idea that a program could use procedures without knowing how the data was represented struck Kay as a good one. It formed the basis for his later ideas about objects." (Dennis Shasha, Cathy Lazere, Out of Their Minds [...], Copernicus, Springer Verlag 1995)

Object-oriented programming is really about distributed programming. And it appears to have been like this from the beginning: "In 1961 [Alan] Kay worked on the problem of transporting data files and procedures from one Air Force air training installation to another and discovered that some unknown programmer had figured out a clever method of doing the job. The idea was to send the data bundled along with its procedures, so that the program at the new installation could use the procedures directly, even without knowing the format of the data files. The procedures themselves could find the information they needed from the data files. The idea that a program could use procedures without knowing how the data was represented struck Kay as a good one. It formed the basis for his later ideas about objects." (Dennis Shasha, Cathy Lazere, Out of Their Minds [...], Copernicus, Springer Verlag 1995)

Object-oriented programming is really about distributed programming. And it appears to have been like this from the beginning: "In 1961 [Alan] Kay worked on the problem of transporting data files and procedures from one Air Force air training installation to another and discovered that some unknown programmer had figured out a clever method of doing the job. The idea was to send the data bundled along with its procedures, so that the program at the new installation could use the procedures directly, even without knowing the format of the data files. The procedures themselves could find the information they needed from the data files. The idea that a program could use procedures without knowing how the data was represented struck Kay as a good one. It formed the basis for his later ideas about objects." (Dennis Shasha, Cathy Lazere, Out of Their Minds [...], Copernicus, Springer Verlag 1995)

Object-oriented programming is really about distributed programming. That's why we didn't say anything about static members.

But local and distributed computing present major differences: The major differences between the two concern the areas of: • latency • memory access • partial failure, and • concurrency One can identify these differences in the pattern presented.

But local and distributed computing present major differences: The major differences between the two concern the areas of: • latency • memory access • partial failure, and • concurrency One can identify these differences in the pattern presented.

But local and distributed computing present major differences: The major differences between the two concern the areas of: • latency • memory access • partial failure, and • concurrency One can identify these differences in the pattern presented.

But local and distributed computing present major differences: The major differences between the two concern the areas of: • latency • memory access • partial failure, and • concurrency One can identify these differences in the pattern presented.

But local and distributed computing present major differences: The major differences between the two concern the areas of: • latency • memory access • partial failure, and • concurrency One can identify these differences in the pattern presented.

But local and distributed computing present major differences: The major differences between the two concern the areas of: • latency • memory access • partial failure, and • concurrency One can identify these differences in the pattern presented.

1. Latency Objects sent back and forth need to be Serializable.

1. Latency Objects sent back and forth need to be Serializable. 2. Memory Access Replace the pointers with object references.

1. Latency Objects sent back and forth need to be Serializable. 2. Memory Access Replace the pointers with object references. 3. Partial Failure Enforce the need to throws java.rmi.RemoteExceptions

1. Latency Objects sent back and forth need to be Serializable. 2. Memory Access Replace the pointers with object references. 3. Partial Failure Enforce the need to throws java.rmi.RemoteExceptions 4. Synchronization The local model must be realistic. It must reflect the truly asynchronous operation in a distributed environment. The only synchronization mechanism we have used is local, at the level of the object. Objects are the only critical regions.

1. Latency Objects sent back and forth need to be Serializable. 2. Memory Access Replace the pointers with object references. 3. Partial Failure Enforce the need to throws java.rmi.RemoteExceptions 4. Synchronization The local model must be realistic. It must reflect the truly asynchronous operation in a distributed environment. The only synchronization mechanism we have used is local, at the level of the object. Objects are the only critical regions.

1. Latency Objects sent back and forth need to be Serializable. 2. Memory Access Replace the pointers with object references. 3. Partial Failure Enforce the need to throws java.rmi.RemoteExceptions 4. Synchronization The local model must be realistic. It must reflect the truly asynchronous operation in a distributed environment. The only synchronization mechanism we have used is local, at the level of the object. Objects are the only critical regions.

1. Latency Objects sent back and forth need to be Serializable. 2. Memory Access Replace the pointers with object references. 3. Partial Failure Enforce the need to throws java.rmi.RemoteExceptions 4. Synchronization The local model must be realistic. It must reflect the truly asynchronous operation in a distributed environment. The only synchronization mechanism we have used is local, at the level of the object. Objects are the only critical regions. A non-distributed system (even multi-threaded) is layered on top of a single operating system which can be used to determine and aid in synchronization and in the recovery of failure. A distributed system, on the other hand, has no single point of resource allocation, or failure recovery, and thus is conceptually very different.

1. Latency Objects sent back and forth need to be Serializable. 2. Memory Access Replace the pointers with object references. 3. Partial Failure Enforce the need to throws java.rmi.RemoteExceptions 4. Synchronization The local model must be realistic. It must reflect the truly asynchronous operation in a distributed environment. The only synchronization mechanism we have used is local, at the level of the object. Objects are the only critical regions. A non-distributed system (even multi-threaded) is layered on top of a single operating system which can be used to determine and aid in synchronization and in the recovery of failure. A distributed system, on the other hand, has no single point of resource allocation, or failure recovery, and thus is conceptually very different.

1. Latency Objects sent back and forth need to be Serializable. 2. Memory Access Replace the pointers with object references. 3. Partial Failure Enforce the need to throws java.rmi.RemoteExceptions 4. Synchronization The local model must be realistic. It must reflect the truly asynchronous operation in a distributed environment. The only synchronization mechanism we have used is local, at the level of the object. Objects are the only critical regions. A non-distributed system (even multi-threaded) is layered on top of a single operating system which can be used to determine and aid in synchronization and in the recovery of failure. A distributed system, on the other hand, has no single point of resource allocation, or failure recovery, and thus is conceptually very different. (see Waldo et al., A Note on Distributed Computing, SMLI TR-94-29)

1. Latency Objects sent back and forth need to be Serializable. 2. Memory Access Replace the pointers with object references. 3. Partial Failure Enforce the need to throws java.rmi.RemoteExceptions 4. Synchronization The local model must be realistic. It must reflect the truly asynchronous operation in a distributed environment. The only synchronization mechanism we have used is local, at the level of the object. Objects are the only critical regions. A non-distributed system (even multi-threaded) is layered on top of a single operating system which can be used to determine and aid in synchronization and in the recovery of failure. A distributed system, on the other hand, has no single point of resource allocation, or failure recovery, and thus is conceptually very different. (see Waldo et al., A Note on Distributed Computing, SMLI TR-94-29)

So what we are presenting here is just a discipline of programming So what we are presenting here is just a discipline of programming. A style. A technique. "The class of locally distributed objects also forms a group that can lead to significant gains in software modularity. Applications made up of collections of such objects would have the advantageof forced and guaranteed separation between the interface to an object and the implementation of that object, and would allow the replacement of one implementation with another without affecting other parts of the system." (Waldo et al., A Note on Distributed Computing). So cell phones are useful. Even though when we use them we are inherently dealing with specific issues of latency, (memory) addressing, partial failure and concurrency. But for the most part they're by and large transparent.

So what we are presenting here is just a discipline of programming So what we are presenting here is just a discipline of programming. A style. A technique. "The class of locally distributed objects also forms a group that can lead to significant gains in software modularity. Applications made up of collections of such objects would have the advantageof forced and guaranteed separation between the interface to an object and the implementation of that object, and would allow the replacement of one implementation with another without affecting other parts of the system." (Waldo et al., A Note on Distributed Computing). So cell phones are useful. Even though when we use them we are inherently dealing with specific issues of latency, (memory) addressing, partial failure and concurrency. But for the most part they're by and large transparent.

So what we are presenting here is just a discipline of programming So what we are presenting here is just a discipline of programming. A style. A technique. "The class of locally distributed objects also forms a group that can lead to significant gains in software modularity. Applications made up of collections of such objects would have the advantageof forced and guaranteed separation between the interface to an object and the implementation of that object, and would allow the replacement of one implementation with another without affecting other parts of the system." (Waldo et al., A Note on Distributed Computing). So cell phones are useful. Even though when we use them we are inherently dealing with specific issues of latency, (memory) addressing, partial failure and concurrency. But for the most part they're by and large transparent.

So what we are presenting here is just a discipline of programming So what we are presenting here is just a discipline of programming. A style. A technique. "The class of locally distributed objects also forms a group that can lead to significant gains in software modularity. Applications made up of collections of such objects would have the advantage of forced and guaranteed separation between the interface to an object and the implementation of that object, and would allow the replacement of one implementation with another without affecting other parts of the system." (Waldo et al., A Note on Distributed Computing). So cell phones are useful. Even though when we use them we are inherently dealing with specific issues of latency, (memory) addressing, partial failure and concurrency. But for the most part they're by and large transparent.

So what we are presenting here is just a discipline of programming So what we are presenting here is just a discipline of programming. A style. A technique. "The class of locally distributed objects also forms a group that can lead to significant gains in software modularity. Applications made up of collections of such objects would have the advantage of forced and guaranteed separation between the interface to an object and the implementation of that object, and would allow the replacement of one implementation with another without affecting other parts of the system." (Waldo et al., A Note on Distributed Computing). So cell phones are useful. Even though when we use them we are inherently dealing with specific issues of latency, (memory) addressing, partial failure and concurrency. But for the most part they're by and large transparent.

So what we are presenting here is just a discipline of programming So what we are presenting here is just a discipline of programming. A style. A technique. "The class of locally distributed objects also forms a group that can lead to significant gains in software modularity. Applications made up of collections of such objects would have the advantage of forced and guaranteed separation between the interface to an object and the implementation of that object, and would allow the replacement of one implementation with another without affecting other parts of the system." (Waldo et al., A Note on Distributed Computing). So cell phones are useful. Even though when we use them we are inherently dealing with specific issues of latency, (memory) addressing, partial failure and concurrency. But for the most part they're by and large transparent.

Conclusions 1. One can take advantage of what was presented if one follows the pattern of development, based on simple object-oriented principles. 2. Once developed the code can be tested locally, in a controlled, and significantly more predictable environment. 3. Increased separation of roles (if the pattern is followed then obtaining the distributed version of it amounts only to marking interfaces as remote and decorating the methods signature with the remote exceptions that now might be thrown, plus serializability) 4. Because of this using RMI for networking is essentially equivalent to using try/catch blocks for exception handling: the impact on productivity should (or could) be significant. 5. The pattern only uses simple inheritance and interfaces.

Conclusions 1. One can take advantage of what was presented if one follows the pattern of development, based on simple object-oriented principles. 2. Once developed the code can be tested locally, in a controlled, and significantly more predictable environment. 3. Increased separation of roles (if the pattern is followed then obtaining the distributed version of it amounts only to marking interfaces as remote and decorating the methods signature with the remote exceptions that now might be thrown, plus serializability) 4. Because of this using RMI for networking is essentially equivalent to using try/catch blocks for exception handling: the impact on productivity should (or could) be significant. 5. The pattern only uses simple inheritance and interfaces.

Conclusions 1. One can take advantage of what was presented if one follows the pattern of development, based on simple object-oriented principles. 2. Once developed the code can be tested locally, in a controlled, and significantly more predictable environment. 3. Increased separation of roles (if the pattern is followed then obtaining the distributed version of it amounts only to marking interfaces as remote and decorating the methods signature with the remote exceptions that now might be thrown, plus serializability) 4. Because of this using RMI for networking is essentially equivalent to using try/catch blocks for exception handling: the impact on productivity should (or could) be significant. 5. The pattern only uses simple inheritance and interfaces.

Conclusions 1. One can take advantage of what was presented if one follows the pattern of development, based on simple object-oriented principles. 2. Once developed the code can be tested locally, in a controlled, and significantly more predictable environment. 3. Increased separation of roles (if the pattern is followed then obtaining the distributed version of it amounts only to marking interfaces as remote and decorating the methods signature with the remote exceptions that now might be thrown, plus serializability) 4. Because of this using RMI for networking is essentially equivalent to using try/catch blocks for exception handling: the impact on productivity should (or could) be significant. 5. The pattern only uses simple inheritance and interfaces.

Conclusions 1. One can take advantage of what was presented if one follows the pattern of development, based on simple object-oriented principles. 2. Once developed the code can be tested locally, in a controlled, and significantly more predictable environment. 3. Increased separation of roles (if the pattern is followed then obtaining the distributed version of it amounts only to marking interfaces as remote and decorating the methods signature with the remote exceptions that now might be thrown, plus serializability) 4. Because of this using RMI for networking is essentially equivalent to using try/catch blocks for exception handling: the impact on productivity should (or could) be significant. 5. The pattern only uses simple inheritance and interfaces.

Bottom Line The network is the computer.

Bottom Line The network is the computer.

Bottom Line The network is the computer.