Explanation
of Code
Import necessary packages.
import java.rmi.*;
import java.rmi.server.*;
import java.net.MalformedURLException;
The implementation class declares which remote interface(s) it is implementing.
Here is the HelloServerImpl class declaration:
public class HelloServerImpl
extends UnicastRemoteObject
implements HelloInterface{
By extending UnicastRemoteObject, the
HelloServerImpl class can be used to
create and export a remote object, which uses RMI(s) default sockets-based
transport for communication and runs all the time.
The constructor for a remote class provides the same functionality
as the constructor for a non-remote class. The constructor for this
class simply prints a small message.
public HelloServerImpl()
throws RemoteException {
System.out.println("Creating server Object");
Our next task is to provide implementation for each remote method.
In this example, the remote interface contains only one remote method
getMessage(). Here is the implementation
for the getMessage() method, which returns
the string "Hello World" to the client:
public String getMessage()
throws RemoteException {
return "Hello World";
}
Return value from a remote method may be an object, as long as that
object implements the interface java.io.Serializable
or java.io.Externalizable.
The return type of the getMessage()
is a String object which implements the Serializable
interface. When a non-remote object is passed to another machine,
the JVM makes a copy and sends that copy across the network (see
Figure 3.2).
Figure 3.2
This server will run as a stand alone application, so it must declare
a main() method.
public static void main(String []helloWorld) {
try {
//create a server object
HelloServerImpl helloServer = new HelloServerImpl();
//bind the server
Naming.rebind("rmi://localhost:1099/Server",helloServer);
System.out.println("Server Ready");
}catch(RemoteException ex) {
System.out.println("Error " +ex.getMessage());
}
catch(MalformedURLException ex) {
System.out.println("Error " +ex.getMessage());
}
}
The main method of the
server creates one or more instances of the remote object implementation,
which provides the service. For example:
HelloServerImpl helloServer = new
HelloServerImpl();
The RMI system provides a registry service (rmiregistry) that
can be used to bind a URL-formatted name of the form "protocol// host:port/objectname"
to the remote object, where protocol is the protocol used, host
is the host name(remote or local), port is the port number on
which the registry is running, and objectname is a simple string
name. For example:
Naming.rebind("rmi://localhost:1099/Server",helloServer);
|
localhost
is a special IP address.
|
The protocol is assumed to be rmi, so you can omit rmi. By default,
the registry runs on port number 1099. If the registry is running on
the default port, 1099, the port number can be omitted. A port is a
unique place within the machine. Port numbers can range from 1 to 65535;
however, ports 1 to 1023 are reserved. If the machine name is left,
the local machine is assumed. So protocol, host and port are optional.
Therefore:
Naming.rebind("rmi://localhost:1099/Server",helloServer)
and
Naming.rebind("Server",helloServer)
are same.
We could use a bind()
call instead of rebind(),
but if the objectname is already in use then bind()
method throws an AlreadyBoundException.
The rebind() method always
binds the name to object as it replaces any object reference with the
same name that is already in the registry. The
rebind() method takes two arguments. The first is a URL-formatted
name associated with the remote object and the second is a reference
to the remote object on which methods will be invoked.
|
An application can
bind or unbind only to a registry running on the same machine
(local machine). A lookup, however, can be done from any machine.
|
|