To accomplish this, we need to:
Note: The terms "remote object implementation", "object implementation," and "implementation" may be used interchangeably to refer to the class, examples.hello.HelloImpl, which implements Hello, an extension of Remote.It must be declared public. Otherwise, unless a client is in the same package as the remote interface, the client will get an error when attempting to load a remote object that implements the remote interface. It extends the java.rmi.Remote interface. Each method must declare java.rmi.RemoteException (or a superclass of RemoteException ) in its throws clause.
import java.rmi.*;public interface Hello extends Remote
{
String sayHello() throws RemoteException;
}
A "server" class in this context, is the class which has a main method that:Implement at least one Remote interface. Define the constructor for the remote object.
The class that contains this main method could be the implementation class itself, or another class.creates an instance of the remote object implementation, and binds that instance to a name in the rmiregistry.
In this example, the main method is part of examples.hello.HelloImpl. The server program needs to:
An explanation of each of these steps follows the source for HelloImpl.java:Instantiate the remote object. Register the remote object with the rmiregistry.
import java.rmi.Naming;
public
class HelloImpl extends
UnicastRemoteObject
implements Hello
{
public HelloImpl() throws
RemoteException {}
public String sayHello() { return "Hello world!"; }
public static void main(String args[])
{
try
{
HelloImpl obj = new HelloImpl();
// Bind this object instance to the name "HelloServer"
Naming.rebind("HelloServer", obj);
}
catch (Exception
e)
{
System.out.println("HelloImpl err: " + e.getMessage());
e.printStackTrace();
}
}
}
When you extend java.rmi.server.UnicastRemoteObject, your class is automatically exported upon creation.
Because the object export could potentially throw a java.rmi.RemoteException, you must define a constructor that throws a RemoteException, even if the constructor does nothing else. The no-argument constructor for the superclass, UnicastRemoteObject, declares the exception RemoteException in its throws clause, so your constructor must also declare that it can throw RemoteException. A RemoteException can occur during construction if the attempt to export the object fails--due to, for example, communication resources being unavailable or the appropriate stub class not being found.
The constructor exports the remote object: Once created, the remote object is ready to accept incoming calls.HelloImpl obj = new HelloImpl();
The RMI system provides a remote object registry that allows you to bind a URL-formatted name of the form "//host/objectname" to the remote object, where objectname is a simple string name.
The RMI registry is a simple server-side name server that allows remote clients to get a reference to a remote object.
It typically is used to locate only the first remote object an RMI client needs to talk to. Then, that first object in turn, provides application-specific support getting references for other objects.
For example, the reference can be obtained as a parameter to, or a return value from, another remote method call.
Once a remote object is registered in the rmiregistry, clients can:
Naming.rebind("HelloServer", obj);
The constructed URL-string that is passed as a parameter to the Naming.lookup method must include the server's hostname.
import java.rmi.RMISecurityManager;
import java.rmi.Naming;
import java.rmi.RemoteException;public class HelloClient
{
public static void main(String arg[])
{
String message = "blank";// I download server's stubs ==> must set a SecurityManager
System.setSecurityManager(new RMISecurityManager());try
{
Hello obj = (Hello) Naming.lookup( "//" +
"lysander.cs.ucsb.edu" +
"/HelloServer"); //objectname in registry
System.out.println(obj.sayHello());
}
catch (Exception e)
{
System.out.println("HelloClient exception: " + e.getMessage());
e.printStackTrace();
}
}
}
Set the security manager, so that the client can download the stub code. Get a reference to the remote object implementation (advertised as "HelloServer") from the server host's rmiregistry. Invoke the remote sayHello method on the server's remote object
To compile the Java source files, run the javac command as follows:
javac -d $HOME/myclasses
Hello.java HelloImpl.java HelloClient.java
For example, to create the stub and skeleton for the HelloImpl remote object implementation, run rmic like this:
rmic HelloImpl
If you start the rmiregistry, and it can find your stub classes in its CLASSPATH, it will ignore the server's java.rmi.server.codebase property, and as a result, your client(s) will not be able to download the stub code for your remote object.
For example, on Solaris:To start the registry on the server, execute the rmiregistry command. This command produces no output and is typically run in the background. For more on the rmiregistry, please refer to the Solaris rmiregistry manual page or the Win32 rmiregistry manual page.
rmiregistry &For example, on Windows 95 or Windows NT:
start rmiregistry
- For Solaris:
java HelloImpl &
- For Windows:
java HelloImpl
After running the client, you will see "Hello world!".java HelloClient