51
Chapter 5: Distributed systems with JAVA: sockets, RMI , Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHIT INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Embed Size (px)

Citation preview

Page 1: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Chapter 5: Distributed systems

with JAVA: sockets, RMI , Threads

Rufin Soh

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 2: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Content

1. Recalls on Networking

2. Java SocketsWhat Is a Socket?Why Java Sockets? Socket: Implementing a ClientSocket: Implementing a ServerRunning the Programs

3. JAVA Threads

4. JAVA RMIJAVA RMI vs other MiddlewaresJava-RMI Working modeProgramming RMIWriting a RMI server

5. JAVA RMIRMI server skeletonWriting a RMI clientRunning the client and serverRMI and java securityJava RMI InternalsWhat is a codebase?How codebase is used RMI and Applets RMI: multiple clients vs the same server object Downloading RMI stubsRMI Command-line examplesRMI TroubleshootingRMI deployment examples

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 3: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Content

1. Recalls on Networking

2. Java SocketsWhat Is a Socket?Why Java Sockets? Socket: Implementing a ClientSocket: Implementing a ServerRunning the Programs

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 4: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Recalls on NetworkingTCP( Transport Control Protocol )

Is a connection-based protocol that provides a reliable flow of data between two computers. Example applications: HTTP, FTP, Telnet, SMTP.

UDP(User Datagram Protocol )Is a protocol that sends independent packets of data, called datagrams, from one computer to another with no guarantees about arrival. Example applications: clock server, Ping.

Understanding Ports The TCP and UDP protocols use ports to map incoming data to a particular process running on a computer.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 5: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

What Is a Socket? A socket is one endpoint of a two-way communication link between two programs running on the network.  A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sent.

Normally, a server runs on a specific computer and has a socket that is bound to a specific port number.

The server just waits, listening to the socket for a client to make a connection request.

On the client-side: The client knows the hostname of the machine on which the server is running and the port number to which the server is connected.

To make a connection request, the client tries to rendezvous with the server on the server's machine and port.

 

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 6: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

What Is a Socket? If everything goes well, the server accepts the connection. Upon acceptance, the server gets a new socket bound to a different port. It needs a new socket (and consequently a different port number) so that it can continue to listen to the original socket for connection requests while tending to the needs of the connected client.

On the client side, if the connection is accepted, a socket is successfully created and the client can use the socket to communicate with the server. Note that the socket on the client side is not bound to the port number used to rendezvous with the server. Rather, the client is assigned a port number local to the machine on which the client is running.

The client and server can now communicate by writing to or reading from their sockets.  

 

 

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 7: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Why Java Sockets? You might wonder why you might choose to use sockets to communicate with remote objects when RMI is availble? Here are two possible reasons:

To communicate with non-java objects and programs: Not all software on networks is written in Java-- at least, not yet.  Until it is, from time to time you'll need to interface a Java program with a non-Java program.

Sockets are a good way to do this, because data transmitted over a socket is reduced to its any languages, running on almost any platform, can deal with a stream of bytes.

To communicate as efficiently as possible.

The convenience of RPC, RMI, and other facilities extract a price in the form of processing overhead. 

A well-designed socket interface between programs can outperform one based on such higher-level facilities.  If you server must handle large volumes of requests, this may be important to you.

Java Socket Classes

The Java.net package provides following two classes:

Socket

ServerSocket

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 8: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Socket: Implementing a ClientCreate a Socket object.

Create an output stream that can be used to send info to the Socket.

Create an input stream to read the response from the server.

Do I/O with input and output streams.

Close the socket when done.

Socket Client = new Socket(?hostname,?portNumber);

PrintStream out = new PrintStream(client.getOutputStream());

DataInputStream in = new DataInputStream(client.getInputStream());

•client.close()

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 9: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Socket: Implementing a ServerCreate a SocketServer object.

Create a Socket object from the ServerSocket.

Create an input stream to read input from the client.

Create an output stream that can be used to send info back to the client.

Do I/O with input and output streams.

Close the socket when done.  

ServerSocket listenSocket = new ServerSocket(portNumber).

While (someCondition) {         Socket server = listenSocket.accept();         doSomethingWith(server);     }

DataInputStream in = new DataInputStream(server.getInputStream());

PrintStream out = new PrintStream(server.getOutputStream());

server.close()

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 10: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Running the ProgramsYou must start the server program first. To do this,

Run the server program using the Java interpreter, just as you would run any other Java application. Remember to run the server on the machine that the client program specifies when it creates the socket.

Next, run the client program. Note that you can run the client on any machine on your network; it does not have to run on the same machine as the server.

If you are too quick, you might start the client before the server has a chance to initialize itself and begin listening on the port. If this happens, you will see a stack trace from the client. just restart the client.

If you forget to change the server host name in the source code for the MySocketClient program, you will see an error message:

To keep our SocketServer example simple, we designed it to listen for and handle a single connection request. However, multiple client requests can come into the same port and, consequently, into the same ServerSocket object.

Client connection requests are queued at the port, so the server must accept the connections sequentially.

However, the server can service them simultaneously through the use of threads - one thread per each client connection.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 11: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

JAVA Threads

The basic flow of logic in a threaded server is this:

From a logical point of view, multithreading means multiple lines of a single program can be executed at the same time, however, it is not the same as starting a program twice and saying that there are multiple lines of a program being executed at the same time.

Creating threads

Two ways of creating threads:

• implementing the runnable interface.

• Extending the Thread class is the way Java inherits methods and variables from this parent class

while (true) { accept a connection ; create a thread to deal with the client ;end while

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 12: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Content

1. Recalls on Networking

2. Java Sockets

3. JAVA Threads

4. JAVA RMIJAVA RMI vs other MiddlewaresJava-RMI Working modeProgramming RMIWriting a RMI serverRMI server skeletonWriting a RMI clientRunning the client and serverRMI and java security

5. JAVA RMIJava RMI InternalsWhat is a codebase?How codebase is used RMI and Applets RMI: multiple clients vs the same server object Downloading RMI stubsRMI Command-line examplesRMI TroubleshootingRMI deployment examples

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 13: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

JAVA RMI

Remote Method Invocation (RMI) is the object equivalent of Remote Procedure Calls (RPC).

While RPC allows you to call procedures over a network, RMI invokes an object's methods over a network.

In the RMI model,

the server defines objects that the client can use remotely.

The clients can now invoke methods of this remote object as if it were a local object running in the same virtual machine as the client.

RMI hides the underlying mechanism of transporting method arguments and return values across the network.

In Java-RMI, an argument or return value can be of any primitive Java type or any other Serializable Java object.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 14: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Java-RMI Working mode

Since both the client and the server may reside on different

machines/processes, there needs to be a mechanism that can establish a

relationship between the two.

Java-RMI uses a network-based registry program called RMIRegistry to

keep track of the distributed objects. (Note: The RMI Registry is an RMI

server itself!!!)

The RMI Registry

The server object makes methods available for remote invocation by

binding it to a name in the RMI Registry.

The client object, can thus check for the availability of a certain server

object by looking up its name in the registry.

The RMI Registry thus acts as a central management point for Java-RMI.

The RMI Registry is thus a simple name repository. It does not address the

problem of actually invoking remote methods.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 15: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Java-RMI Working modeStubs and Skeletons

Since the two objects may physically reside on different

machines, a mechanism is needed to transmit the client's request

to invoke a method on the server object to the server object and

provide a response.

Java-RMI uses an approach similar to RPC in this regard. The

code for the server object must be processed by an RMI compiler

called rmic, which is part of the JDK.

Stubs & Skeletons

Remote Reference layer

Transport layer

Stubs & Skeletons

Remote Reference layer

Client Program Server Program

RMI System

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 16: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Java-RMI Working mode

Stubs and Skeletons

The rmic compiler generates two files: a stub and a skeleton.

The stub resides on the client machine and the skeleton resides on the

server machine.

When a client invokes a server method,

• The JVM looks at the stub to do type checking.

• The request is then routed to the skeleton on the server,

• Which in turn calls the appropriate method on the server object. In other words,

the stub acts as a proxy to the skeleton and the skeleton is a proxy to the actual

remote method.

Server Program

RMI System

Client Program

Interface Implementation

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 17: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Programming RMI

Remote Method Invocation (RMI) facilitates object function calls between Java

Virtual Machines (JVMs).

JVMs can be located on separate computers - yet one JVM can invoke

methods belonging to an object stored in another JVM.

Methods can even pass objects that a foreign virtual machine has never

encountered before, allowing dynamic loading of new classes as required.

This is a powerful feature!

Consider the follow scenario :

Developer A writes a service that performs some useful function. He regularly

updates this service, adding new features and improving existing ones.

Developer B wishes to use the service provided by Developer A. However, it's

inconvenient for A to supply B with an update every time.

Java RMI provides a very easy solution! Since RMI can dynamically load new

classes, Developer B can let RMI handle updates automatically for him. Developer A

places the new classes in a web directory, where RMI can fetch the new updates as

they are required.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 18: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Programming RMI

Connections made when client uses RMI

Firstly, the client must contact an RMI registry, and request the name of the service.

Developer B won't know the exact location of the RMI service, but he knows enough

to contact Developer A's registry. This will point him in the direction of the service

he wants to call..

Developer A's service changes regularly, so Developer B doesn't have a copy of the

class. Not to worry, because the client automatically fetches the new subclass from

a webserver where the two developers share classes. The new class is loaded into

memory, and the client is ready to use the new class. This happens transparently for

Developer B - no extra code need to be written to fetch the class.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 19: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Writing a RMI server

We'll create a service that can calculate the square of a number, and the power

of two numbers (238 for example).

Due to the large size of the numbers, we'll use the java.math.BigInteger class

for returning values rather than an integer or a long.

Writing an interface

The first thing we need to do is to agree upon an interface, An interface description

is a description of the methods we will allow remote clients to invoke. Let's consider

exactly what we'll need.

1. A method that accepts as a parameter an integer, squares it, and returns a BigInteger

public BigInteger square ( int number_to_square );

2. A method that accepts as a parameter two integers, calculates their power, and returns a

BigInteger

public BigInteger power ( int num1, int num2 );

Once we've decided on the methods that will compose our service, we have to

create a Java interface.

An interface is a method which contains abstract methods; these methods

must be implemented by another class.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 20: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Writing a RMI serverHere's the source code for our service (Interface) that calculates powers.

Our interface extends java.rmi.Remote, which indicates that this is a remote

service.

We provide method definitions for our two methods (square and power), and

the interface is complete.

import java.math.BigInteger;import java.rmi.*;

//// PowerService Interface//// Interface for a RMI service that calculates powers//public interface PowerService extends java.rmi.Remote{// Calculate the square of a numberpublic BigInteger square ( int number )throws RemoteException;

// Calculate the power of a numberpublic BigInteger power ( int num1, int num2) throws RemoteException;}

This is where to define your interface

This is where to define it as RMI

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 21: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Writing a RMI serverImplementing the interface

The next step is to implement the interface, and provide methods for the square and

power functions.

Implementing the interface is a little more tricky - we actually have to write the

square and power methods! Don't worry if you're not sure how to calculate squares

and powers, this isn't a math lesson. The real code we need to be concerned about

is the constructor and main method.

We have to declare a default constructor, even when we don't have any initialization

code for our service. This is because our default constructor can throw a

java.rmi.RemoteException, from its parent constructor in UnicastRemoteObject.

Sound confusing? Don't worry, because our constructor is extremely simple.

public PowerServiceServer () throws RemoteException    {        super();    }

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 22: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Writing a RMI serverImplementing the interface

Our implementation of the service also needs to have a main method. The main

method will be responsible for creating an instance of our PowerServiceServer, and

registering (or binding) the service with the RMI Registry. Our main method will also

assign a security manager to the JVM, to prevent any nasty surprises from remotely

loaded classes. In this case, a security manager isn't really needed, but in more

complex systems where untrusted clients will be using the service, it is critical. 

    public static void main ( String args[] ) throws Exception    {        // Assign a security manager, in the event that dynamic       // classes are loaded       if (System.getSecurityManager() == null)            System.setSecurityManager ( new RMISecurityManager() );

       // Create an instance of our power service server ...       PowerServiceServer svr = new PowerServiceServer();

       // ... and bind it with the RMI Registry       Naming.bind ("PowerService", svr);

       System.out.println ("Service bound....");    }

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 23: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI server skeletonOnce the square and power methods are added, our server is complete. Here's the full

source code skeleton for the PowerServiceServer.

import java.math.*;import java.rmi.*;import java.rmi.server.*;

//// PowerServiceServer//// Server for a RMI service that calculates powers//public class PowerServiceServer extends UnicastRemoteObjectimplements PowerService{ public PowerServiceServer () throws RemoteException {} // Calculate the square of a number public BigInteger square ( int number ) throws RemoteException {} // Calculate the power of a number public BigInteger power ( int num1, int num2) throws RemoteException {}

public static void main ( String args[] ) throws Exception {}}

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 24: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Writing a RMI clientWhat good is a service, if you don't write a client that uses it?

Writing clients is the easy part - all a client has to do is

• call the registry to obtain a reference to the remote object,

• and call its methods.

All the underlying network communication is hidden from view, which makes RMI

clients simple.

Our client must first assign a security manager, and then obtain a reference to the

service.

Note that the client receives an instance of the interface we defined earlier, and not

the actual implementation.

Some behind-the-scenes work is going on, but this is completely transparent to the

client.

    // Assign security manager    if (System.getSecurityManager() == null)    {        System.setSecurityManager   (new RMISecurityManager());    } }

   

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 25: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Writing a RMI client

To identify a service, we specify an RMI URL.

The URL contains the hostname on which the service is located, and the logical

name of the service.

This returns a PowerService instance, which can then be used just like a local object

reference.

We can call the methods just as if we'd created an instance of the remote

PowerServiceServer ourselves.

// Call registry for PowerService    PowerService service = (PowerService) Naming.lookup("rmi://" + args[0] + "/PowerService");

// Call remote methodSystem.out.println    ("Answer : " + service.square(value));

// Call remote methodSystem.out.println    ("Answer : " + service.power(value,power));

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 26: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Running the client and server

1. Start the rmiregistry

• Windows users should do the following (assuming that your java\bin

directory is in the current path): - start rmiregistry

• Unix users should do the following: - rmiregistry &

2. Compile the server

• Compile the server, and use the rmic tool to create stub files.

3. Start the server

• From the directory in which the classes are located, type the following:-

• java PowerServiceServer

4. Start the client

• You can run the client locally, or from a different machine. In either case,

you'll need to specify the hostname of the machine where you are running

the server. If you're running it locally, use localhost as the hostname.

• java PowerServiceClient localhost

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 27: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI and java securityIf you running the client or server with JDK1.2, then you'll need to change the

security settings.

You'll need to specify a security policy file (a sample is included with the

source code and classes) when you run the client and server.

The following changes should be made when running the server

java -Djava.security.policy=java.policy PowerServiceServer

The following changes should be made when running the client

java -Djava.security.policy=java.policy PowerServiceClient localhost

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 28: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

What is a codebase?

A codebase can be defined as a source, or a place, from which to load classes

into a Java virtual machine.

For example, if you invited a new friend over for dinner, you would need to give

that friend directions to the place where you lived, so that he or she could locate

your house.

Similarly, you can think of a codebase as the directions that you give to a JVM,

so it can find your [potentially remote] classes.

You can think of your CLASSPATH as a "local codebase", because it is the list

of places on disk from which you load local classes.

When loading classes from a local disk-based source, your CLASSPATH

variable is consulted.

Your CLASSPATH can be set to take either relative or absolute path names to

directories and/or archives of class files.

So just as CLASSPATH is a kind of "local codebase", the codebase used by

applets and remote objects can be thought of as a "remote codebase".

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 29: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

How codebase is used in generalTo interact with an applet, that applet and any classes that it needs to run must be accessible by remote clients.

While applets can be accessed from "ftp://" or local "file:///" URLs, they are usually accessed from a remote HTTP server.

1. The client browser requests an applet class that is not found in the client's CLASSPATH

2. The class definition of the applet (and any other class(es) that it needs) is downloaded from the server to the client using HTTP

3. The applet executes on the client

An HTML source to invoke an applet will contain something like:

The applet's codebase is always relative to the URL of the HTML page in which the <applet> tag is contained.

<applet height=100 width=100 codebase="myclasses/" code="My.class"><param name="ticker"> </applet>

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 30: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

How codebase is used in RMI

Using RMI, applications can create remote objects that accept method calls from

clients in other JVMs.

In order for a client to call methods on a remote object, the client must have a

way to communicate with the remote object.

Rather than having to program the client to speak the remote object's protocol,

RMI uses special classes called stubs that can be downloaded to the client that

are used to communicate with (make method calls on) the remote object.

The java.rmi.server.codebase property value represents one or more URL

locations from which these stubs (and any classes needed by the stubs) can be

downloaded.

Like applets, the classes needed to execute remote method calls can be

downloaded from "file:///" URLs, but like applets, a "file:///" URL generally

requires that the client and the server reside on the same physical host, unless

the file system referred to by the URL is made available using some other

protocol, such as NFS.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 31: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Java RMI Internals

• The RMI Server creates an instance of the 'Server Object' which extends UnicastRemoteObject

• The constructor for UnicastRemoteObject "exports" the Server Object - basically making it available to service incoming RMI calls. A TCP socket which is bound to an arbitrary port number is created and a thread is also created that listens for connections on that socket.

1. The server registers the server object with the registry. This operation actually hands the client-side "stub" for that server object. This stub contains the information needed to "call back" the server when it is invoked (such as the hostname/port of the server listening socket).

Client

Registry

Web server

RMI Server

1

3 RMI

HTTP URLHTTP URL

RMI

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 32: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Java RMI Internals

2. A client obtains this stub by calling the registry, which hands it the stub directly.

3. This is also where the "codebase" comes in: If the server specified a "codebase" to use for clients to obtain the classfile for the stub, this will be passed along to the client via the registry.

4. The client can then use the codebase to resolve the stub class - that is, to load the stub classfile itself).• That is all that the RMIRegistry really does: It holds onto remote object stubs which it

can hand off to clients when requested.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 33: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Java RMI Internals

5. When the client issues a remote method invocation to the server, the stub class

creates a "RemoteCall" which basically

(a) opens a socket to the server on the port specified in the stub itself, and

(b) Sends the RMI header information as described in the RMI spec.

6. The stub class marshalls the arguments over the connection by using methods on

RemoteCall to obtain the output stream which basically returns a subclass of

ObjectOutputStream which knows how to deal with passing objects which extend

java.rmi.Remote, which serializes Java objects over the socket

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 34: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Java RMI Internals

7. The stub class calls RemoteCall.executeCall which causes the RMI to happen.

8. On the server side, when a client connects to the server socket, a new thread is

forked to deal with the incoming call. The original thread can continue listening to

the original socket so that additional calls from other clients can be made.

9. The server reads the header information and creates a RemoteCall of its own to

deal with unmarshalling the RMI arguments from the socket.

10. The server calls the "dispatch" method of the skeleton class (the server-side

"stub" generated by rmic), which calls the appropriate method on the object and

pushes the result back down the wire (using the same 'RemoteCall' interface which

the client used to marshall the arguments). If the server object threw an exception

then the server catches this and marshalls that down the wire instead of the return

value.

11. Back on the client side, the return value of the RMI is unmarshalled (using the

RemoteCall created in step 5 above) and returned from the stub back to the client

code itself. If an exception was thrown from the server that's unmarshalled and re-

thrown from the stub.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 35: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI: multiple clients vs the same server object

All the Clients get stubs which contain the same hostname/port number as the

server-side socket which is listening for calls on the object.

When a client connects, the server forks a new thread to deal with the

incoming request, but keeps listening to that original socket (in another

thread) so that other calls can be made.

There doesn't appear to be any synchronization within the server side

components - if multiple clients simultaneously call into the server object they

can all manipulate the server object state at the same time.

You can of course make methods in your server object "synchronized" to

synchronize access to them.

Now, the RMI specification defines both a "single op" and a "stream" protocol

for RMI calls. The former allows a single RMI call to be made on a socket

which is then closed; the latter allows multiple RMI calls to be issued on the

same socket one after the other.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 36: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI: multiple clients vs the same server object

Sun's RMI implementation appears to be using this latter mechanism which

means that a single client-side stub object will open a single socket to the

server for all of its communication.

Multiple stubs within the same JVM or different JVMs on the same host will

each have their own socket to the server (which might all dispatch calls to the

same server-side object). The net result is that each time you obtain a stub

(from the registry) for a particular server-side object, you will eventually create

a new socket to talk to the server.

So basically:

ON THE SERVER: A single 'UnicastRemoteObject' which ends up creating

multiple threads to listen for calls on this single object - one thread per socket

(basically meaning one thread per client)

ON THE CLIENT: One socket to the server per stub, meaning that if the client

has multiple stubs pointing to the same server object it will have multiple

sockets open to that server.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 37: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI and Applets A remote system can run a program, for example an applet, which has never been installed on its disk

For example, a JVM running from within a web browser can download the bytecodes for subclasses of java.applet.Applet and any other classes needed by that applet.

The system on which the browser is running has most likely never run this applet before, nor installed it on its disk. Once all the necessary classes have been downloaded from the server, the browser can start the execution of the applet program using the local resources of the system on which the client browser is running.

For the first few sections of this document, codebase with regard to applets will be discussed in order to help describe codebase with regard to Java Remote Method Invocation (RMI).

Java RMI takes advantage of this capability to download and execute classes and on systems where those classes have never been installed on disk.

Using the RMI API any JVM, not only those in browsers, can download any Java class file including specialized RMI stub classes, which enable the execution of method calls on a remote server using the server system's resources.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 38: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI and Applets

The notion of a codebase originates from the use of ClassLoaders in the Java programming language.

When a Java program uses a ClassLoader, that class loader needs to know the location(s) from which it should be allowed to load classes.

Usually, a class loader is used in conjunction with an HTTP server that is serving up compiled classes for the Java platform.

The first ClassLoader/codebase pairing that you came into contact with was the AppletClassLoader, and the "codebase" part of the <applet> HTML tag

An HTML source to invoke an applet will contain something like:

to invoke a servlet will contain something like:

<applet height=100 width=100 codebase="myclasses/" code="My.class"><param name="ticker">

</applet>

<servlet codebase="myclasses/" code="My.class"><param name="ticker">

</servlet>

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 39: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI development stepsThe development process is shown bellow where Bob is the server

developer and Alice the client one.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 40: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI development stepsThe different steps Bob must follow to get his server implemented and running are:

1. Define the server interface. The server object declares its service via a remote

interface, that must therefore extends the java.rmi.Remote interface.

2. Write the server code. Bob must provide the Java file containing the server class that

implements its server interface, and that inherits from the

java.rmi.UnicastRemoteObject class. He must also include the code that will install a

SecurityManager and that will register the server interface within the RMI naming

context using the Naming.bind (or rebind) method. The daemon program that is in

charge of the naming service is rmiregistry, and it must of course be running for the

interface registration to succeed(Recall: the RMIregistry is a server itself).

3. Compile the server class. Bob first uses the javac compiler to produce the

server .class file, and secondly, runs the rmic compiler to obtain the stub and skeleton

.class files.

4. Execute the server program. If the rmiregistry daemon is not already running, Bob

must launch it. He can then run the java interpreter with his server .class file.

5. Distribute the stub class. In order to get clients calling the methods of his server, Bob

needs to give them the stub class he has just generated, to Alice for example. This will

enable her code to make successful requests on his server object.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 41: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI Command-line examplesIn the case of an applet, the applet codebase value is embedded in an HTML page, as we saw in the HTML example ..

In the case of Java RMI codebase, rather than having a reference to the class embedded in an HTML page, the client first contacts the RMI registry for a reference to the remote object. Because the remote object's codebase can refer to any URL, not just one that is relative to a known URL,

The value of the RMI codebase must be an absolute URL to the location of the stub class and any other classes needed by the stub class. This value of the codebase property can refer to:

The URL of a directory in which the classes are organized in package-named sub-directories

The URL of a JAR file in which the classes are organized in package-named directories

A space-delimited string containing multiple instances of JAR files and/or directories that meet the criteria above

Note: When the codebase property value is set to the URL of a directory, the value must be terminated by a "/".

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 42: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI Command-line examplesExamples

If the location of your downloadable classes is on an HTTP server named "webvector",

in the directory "export" (under the web root), your codebase property setting might

look like this:

If the location of your downloadable classes is on an HTTP server named "webline", in

a JAR file named "mystuff.jar", in the directory "public" (under the web root), your

codebase property setting might look like this:

Now let's suppose that the location of your downloadable classes has been split

between two JAR files, "myStuff.jar" and "myOtherStuff.jar". If these JAR files are

located on different servers (named "webfront" and "webwave"), your codebase

property setting might look like this:

-Djava.rmi.server.codebase=http://webvector/export/

-Djava.rmi.server.codebase=http://webline/public/mystuff.jar

-Djava.rmi.server.codebase="http://webfront/myStuff.jar http://webwave/myOtherStuff.jar"

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 43: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI Troubleshooting

Any serializable class, including RMI stubs, can be downloaded if your RMI programs are configured properly. Here are the conditions under which dynamic stub downloading will work:

A. The stub class and any of the classes that the stub relies on are served up from a URL reachable from the client.

B. The java.rmi.server.codebase property has been set on the server program (or in the case of activation, the "setup" program) that makes the call to bind or rebind, such that:

• The value of the codebase property is the URL in step A and

• If the URL specified as the value of the codebase property is a directory, it must end in a trailing "/"

C. The rmiregistry cannot find the stub class or any of the classes that the stub relies on in its CLASSPATH. This is so the codebase gets annotated to the stub when the registry does its class load of the stub, as a result of calls to bind or rebind in the server or setup code.

D. The client has installed a SecurityManager that allows the stub to be downloaded. In the Java 2 SDK, Standard Edition, v 1.2 this means that the client must also have a properly configured security policy file.

There are two common problems associated with the java.rmi.server.codebase property, which are discussed next.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 44: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI Troubleshooting

If you encounter a problem running your RMI server

Receipt of a ClassNotFoundException when attempting to bind or rebind a

remote object to a name in the registry. This exception is usually due to a malformed

codebase property, resulting in the registry not being able to locate the remote

object's stubs or other classes needed by the stub.

It is important to note that the remote object's stub implements all the same interfaces

as the remote object itself, so those interfaces, as well as any other custom classes

declared as method parameters or return values, must also be available for download

from the specified codebase.

Most frequently, this exception is thrown as a result of omitting the trailing slash from

the URL value of the property. Other reasons would include: the value of the property is

not a URL; the path to the classes specified in the URL is incorrect or misspelled; the

stub class or any other necessary classes are not all available from the specified URL.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 45: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI Troubleshooting

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:java.lang.ClassNotFoundException: examples.callback.MessageReceiverImpl_Stubjava.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:java.lang.ClassNotFoundException: examples.callback.MessageReceiverImpl_Stubjava.lang.ClassNotFoundException: examples.callback.MessageReceiverImpl_Stubat sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Compiled Code)at sun.rmi.transport.StreamRemoteCall.executeCall(Compiled Code)at sun.rmi.server.UnicastRef.invoke(Compiled Code)at sun.rmi.registry.RegistryImpl_Stub.rebind(Compiled Code)at java.rmi.Naming.rebind(Compiled Code)at examples.callback.MessageReceiverImpl.main(Compiled Code)RemoteException occurred in server thread; nested exception is:java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.lang.ClassNotFoundException: examples.callback.MessageReceiverImpl_Stub

java.rmi.UnmarshalException: Return value class not found; nested exception is:java.lang.ClassNotFoundException: MyImpl_Stubat sun.rmi.registry.RegistryImpl_Stub.lookup(RegistryImpl_Stub.java:109at java.rmi.Naming.lookup(Naming.java:60)at RmiClient.main(MyClient.java:28)

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 46: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI TroubleshootingThis is a list of some Exceptions that may occur During Remote Object Export

When a remote object class is created that extends UnicastRemoteObject, the object is exported, meaning it can receive calls from external Java virtual machines and can be passed in an RMI call as either a parameter or return value. An object can either be exported on an anonymous port or on a specified port. For objects not extended from UnicastRemoteObject, the java.rmi.server.UnicastRemoteObject.exportObject method is used to explicitly export the object.

Exception

java.rmi.server.SkeletonNotFoundException

note: this exception is deprecated as of Java 2 SDK, Standard Edition, v1.2

ContextClass of skeleton not found.

Name collision with class of same name as skeleton causes one of these errors:

Skeleton can't be instantiated Skeleton not of correct class

Bad URL due to wrong codebase. Skeleton not of correct class.

java.rmi.server.ExportException The port is in use by another VM.

Exception

java.rmi.StubNotFoundException ContextClass of stub not found. Name collision with class of same name as stub causes one of these errors: · Stub can't be instantiated · Stub not of correct class Bad URL due to wrong codebase. Stub not of correct class.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 47: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI Troubleshooting

Exception

java.rmi.UnknownHostException

Context

Unknown host.

java.rmi.activation.ActivateFailedException Thrown by RMI runtime when activation fails during a remote call to an activatable object

java.rmi.ConnectException Connection refused to host.

java.rmi.ConnectIOException

java.rmi.MarshalException

java.rmi.NoSuchObjectException

java.rmi.StubNotFoundException

Connection refused to host.

I/O error creating connection.

Attempt to invoke a method on an object that is no longer available.

I/O error marshaling transport header, marshaling call header, or marshaling arguments.

java.rmi.ServerError Any error that occurs while the server is executing a remote method. The ServerError exception object contains the underlying error that was thrown by the server,

java.rmi.AccessException

java.rmi.NotBoundException

Operation disallowed. The registry restricts bind, rebind, and unbind to the same host. The lookup operation can originate from any host.

Attempt to look up a name that is not bound.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 48: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

JAVA RMI vs other Middlewares

Java-RMI is a Java-specific middleware that allows client Java programs to

invoke server Java objects as if they were local.

Java-RMI is tightly coupled with the Java language. Hence there are no

separate IDL mappings that are required to invoke remote object methods.

This is different from DCOM or CORBA where IDL mappings have to be

created to invoke remote methods.

Since Java-RMI is tightly coupled with The Java Language, Java-RMI can

work with true sub-classes. Neither DCOM nor CORBA can work with true

subclasses since they are static object models

Because of this, parameters passed during method calls between machines

can be true Java Objects. This is impossible in DCOM or CORBA at present.

If a process in an RMI system receives an object of a class that it has never

seen before, it can request that its class information be sent over the network.

Over and above all this, Java-RMI supports Distributed Garbage Collection

that ties into the local Garbage Collectors in each JVM.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 49: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI deployment examples

Each main functionality are designed as a totally independent system based on

this architecture:

o PRESENTATION,

o ACQUISITION,

o ACCESS

each functionality is a standalone system which can be used for another goal.

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 50: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI deployment examples

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

Page 51: Chapter 5: Distributed systems with JAVA: sockets, RMI, Threads Rufin Soh Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES

RMI deployment examples

Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES