chapter 5: distributed systems with java: sockets, rmi, threads rufin soh wilfried probst – rufin...
TRANSCRIPT
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
RMI deployment examples
Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES
RMI deployment examples
Wilfried Probst – Rufin Soh INE4481 DISTRIBUTED DATABASES & CLIENT-SERVER ARCHITECTURES