RMI Server Side

Date: 4/8/2002

Introduction

RMI stands for Remote Method Invocation. The idea is that we want to be able to execute methods of a class that is actually sitting on the server.

What appears to happen is that the client object calls the methods of the remote (server-side) object.

client object --> remote object

What actually happens is the client object is making use of a stub. A stub is simply a class file that knows what the methods of the remote object are. The stub will take the information passed to it by the client and serialize it. To serialize means to convert into a byte stream that can be transported over a connection (think of the transporters from Star Trek that "beam" objects from point A to point B). The serialized information is then passed to the server. This process is called marshalling. On the server side, the data is received by a skeleton. The skeleton object de-serializes the data and passes it to the actual remote object. This process is called unmarshalling.

client object --> stub --> skeleton --> remote object

To keep your files organized, and to better understand the files created and/or required by both the client and server sides, you may want to set up one directory for all files created in this lecture, and a different directory for all files created and/or required for the next lecture.

The Server-Side Setup

  1. Create an Interface Class

  2. The purpose of an interface class is to define the method signatures for the implementing class and extends Remote.

    Note that the interface contains method signatures only, no code. A method signature indicates scope, return type, arguments, and exceptions thrown. Take a look at AddressInterface.java for an example of an interface class.

    Note that we are using a class called Vector. This class is similar to a list. We will discuss Vectors in more detail next week.

    The interface class defines methods for each of the actions we wanted to take on our data. Instead of passing strings of data, we will now be passing objects. For example, if I wanted to return a specific address to my front end, I would instantiate a copy of my Address object, set all the properties from my ResultSet, then pass the Address object to the front end.

  3. Create an Implementation Class

  4. The implementation class is where we define the code for the methods. It extends UnicastRemoteObject and implements the interface.

    The code is, for the most part, a cut-and-paste from Assignment #8. The main difference is that the code is being placed into independent methods instead of being part of a switch. Take a look at AddressImplementation.java for an example of an implementation class.

    This class needs to be registered as a service with the server so that it can be found. This is done using JNDI - Java Naming Directory Interface. Refer to the constructor.

  5. Create a Server class
  6. The server class sets the security manager to the RMISecurityManager, using policies that we will set up. It will then start the implementation class as a service. Take a look at AddressServer.java for an example of a server class.
  7. Create a Security Policy
  8. The security policies grants permissions for the users who are permitted to run the remote object. Take a look at wideopen.policy for an example of an un-secure security policy.

  9. Create the stub and skeleton
  10. After the classes are compiled, open a DOS window and change to the directory containing the class files. Then, run the RMI Compiler on the implementation class:

    rmic AddressImplementation

The Server-Side Startup

  1. Open a DOS window and change to the directory containing your class files.
  2. Start the RMI Registry by typing "rmiregistry" and pressing ENTER.
  3. Open another DOS window and change to the directory containing your class files.
  4. Start your server class, but tell it where the security policy is: java -Djava.security.policy=wideopen.policy AddressServer