Previous lesson 4/6 |home| Next lesson 6/6

Remote Method Invocation (Level I)

Design an RMI Client

In the previous sections, we designed a remote interface, a remote object and a server. And now we need to design a client to test the functionality of the server.

What is an RMI client?

A typical RMI cient is an application that gets a remote reference to one or more remote objects in the server, then invokes methods on these remote objects.

Remember that we register a remote object by name "Mortgage" with a TCP port number 1099(default). In our client class, we need some code to look up the object by name "Mortgage" and a TCP port number. When we get the stub class from the RMI server, we can use this stub class to call the remote method.

There are two things you should do before calling the remote method.

  1. Locate a host from the registry mechanism.
  2. Look up the remote object by its name.

How to locate a host?

Use the following code to locate a host.

Registry reg = LocateRegistry.getRegistry(hostName); 

In our example, we will use localhost as the default host. If you run the server in a different computer, you need to give that computer's name as a host name.

How to look up a remote object?

You look up a remote object by its name. So, you must first know the name of the remote object. Remember that we register the remote object by name "Mortgage" in the server's registry. We use code below to look up "Mortgage" object and get a stub back. The stub can be used to access the remote method.

 
Payment stub = (Payment) reg.lookup("Mortgage");

Note that the returned remote object reference should be cast back to the remote interface. In this context, we cast to Payment interface.

The most beautiful thing is that a method invocation on a remote object has the same syntax as a method invocation on a local object when you get the referece to a remote object.

The client class is designed as follows:

 
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {
    private static Payment stub = null;
    private Client() {}

    public static void main(String[] args) {

	double payment, principal = 80000;
        double annualInterest = .065;
        int years = 15;
	try {
	    Registry reg = LocateRegistry.getRegistry("localhost");
	    stub = (Payment) reg.lookup("Mortgage");
	    
	} catch (Exception e) {
	    System.err.println("Client exception thrown: " + e.toString());
	    e.printStackTrace();
	}
        if (args.length == 3) {
           try {
              principal = Double.parseDouble(args[0]);
              annualInterest = Double.parseDouble(args[1]);
              years = Integer.parseInt(args[2]);
           }
           catch (Exception e) {
              System.out.println("Wrong input " + e.getMessage() );
              System.exit(0);
           }
           print(principal, annualInterest, years);
        
        } else {
            System.out.println("Usage: java Client principal annualInterest years ");
            System.out.println("\nFor example: java Client 80000 .065 15 ");
            System.out.println("\nYou will get the output like the following: \n");
	    print(principal, annualInterest, years);
            System.exit(0);
        }        
        
    }
    
    public static void print(double pr, double annRate, int years){
        double mpayment = 0;
        try {
            mpayment = stub.calculatePayment(pr, annRate, years);
        }catch(Exception e) {
            System.out.println("Remote method exception thrown: " + e.getMessage());
        }
        System.out.println("The principal is $" + (int)pr);
        System.out.println("The annual interest rate is " + annRate*100 +"%");
        System.out.println("The term is " + years + " years");
        System.out.println("Your monthly payment is $" + mpayment);
    }
}

Note that we use the returned stub from lookup() method to call the remote method calculatePayment() and pass three parameters obtained from the command-line. We have to use try/catch block to locate RMI registry, look up stub class and call the remote method. If the server has a problem or the remote method has a failure, the client side should be able to know it through the catch clause.

All right, now we have created a simple client\server system. Let's compile and test it.

Check your skill

Design a client class that can be used to test the functionality of the server you created in the previous sections.

A possible solution: HelloClient.java

page 1  page 2  page 3  page 4  page 5  page 6  Previous lesson 4/6 |home| Next lesson 6/6