Java Remote Method Invocation (RMI)
Java Remote Method Invocation (RMI)
Objectives
- Develop a Java program that utilizes remote method invocation.
Client-Server Program Review
- Server-side (prior to client connection):
- Programmatically starts the server.
- Waits perpetually for an incoming connection.
- Client-side (prior to data being received by the server):
- Collects data (GUI, file, console, etc.).
- References a class that would represent the data collected.
- Populates the object using the collected data.
- Transforms object to a “streamable data” (usually a string of characters).
- Programmatically connects to a server.
- Gets output stream.
- Sends object to server via the output stream.
- Server-side (when a client connects to the server):
- Allows connection from clients.
- Gets input stream.
- Accepts string from client using input stream.
- Parses accepted string.
- References a class that would represent the data collected.
- Populates the object using the collected data.
- Saves object in the database.
- Gets output stream.
- Sends response to the client.
- Client-side (upon receiving response from the server):
- Gets input stream.
- Parses text collected.
- Executes confirmation.
Distributed Systems
- A distributed system is a combination of several computers with separate memory, linked over a network, on which it is possible to run an application.
- Remote Procedure Call (RPC) is the first successful distributed technology used in distributed systems/applications.
- The idea of RPC goes back to at least 1976.
Disadvantages of RPC:
- RPC is not, by design, object-oriented.
- RPC supports a limited set of data types, therefore it is not suitable for passing and returning objects.
- RPC requires the programmer to learn a special Interface Definition Language (IDL) to describe the functions that can be invoked remotely.
Distributed Programming in Java
- Developers who program using the Java programming language can choose several solutions for creating distributed application programs:
- Java RMI technology
- Java IDL technology (for CORBA programmers)
- Enterprise JavaBeans technology (not covered in the course)
- Web services
Java RMI
- Java Remote Method Invocation (Java RMI) enables the programmer to create distributed Java applications, in which the methods of remote Java objects can be invoked from other Java virtual machines, possibly on different hosts.
The Java RMI process:
- Create an interface that will be shared by both the client and the server.
- Create a server that will implement the interface.
- Start “rmiregistry” the “proxy”.
- Run the server – make sure the server binds the object (2) to the registry.
- Create a client that will get the method implement from the registry.
Sample program 1: Create a method that will be invoked remotely.
- This method shall accept string value as parameter and it shall return the number of characters in the string.
Steps to create the RMI server:
- Create/design an interface that will extend Remote interface (all methods should throw RemoteException).
- Create a class that will implement the interface (make sure that the class will extend UnicastRemoteObject and implement the interface above).
- In the main method, do the following:
- Create an instance of the created class
- Create a registry class and start/create a running registry
- Register the instance of class to the registry using a unique name
Interface definition:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface SampleRemote extends Remote {
int countCharacters(String value) throws RemoteException;
}
- For this particular example, the task to be done is considered simple and merging the main method with the implementing class of the interface is the more appropriate situation.
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class RMIServer extends UnicastRemoteObject implements SampleRemote {
public RMIServer() throws RemoteException {}
@Override
public int countCharacters(String value) throws RemoteException {
return value.length();
}
public static void main(String[] args) {
try {
SampleRemote stub = new RMIServer();
Registry reg = LocateRegistry.createRegistry(10000);
reg.rebind("samplermi", stub);
System.out.println("Sample RMI bound");
} catch (RemoteException exc) {
exc.printStackTrace();
}
}
}
- In case that the implementing class has a considerable number of operations to be defined, it is best to separate the main class from the implementing class.
- When this happens, the implementing class can be referred to as the servant class and the main class as the server class.
Steps to create the RMI client:
- Use the same interface declared in the RMI server
- In the main method, do the following:
- Create a registry class and locate the running registry
- Lookup the name of the remote instance in the server and assign it to the named interface using a cast
- Execute the methods (remotely)
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
// an additional import statement may be needed in case the interface belongs to
// a different package
public class RMIClient {
public static void main(String[] args) {
try {
Registry registry = LocateRegistry.getRegistry("localhost", 10000);
SampleRemote remote = (SampleRemote) registry.lookup("samplermi");
String test = "The quick brown fox jumps over the lazy dog.";
System.out.println("\"" + test + "\" : " +
remote.countCharacters(test));
test = "Saint Louis University";
System.out.println("\"" + test + "\" : " +
remote.countCharacters(test));
} catch (RemoteException | NotBoundException exc) {
exc.printStackTrace();
}
}
}