Java RMI - registry questions

C

Christian Hvid

Can anyone help with these Java 5 RMI related questions?

I want to make a very basic RMI application; something needs to run as
a "background job" that I should be able to query the state of and
start and shutdown cleanly.

* Is there a clean way to shutdown a registry created locally in the
server code?

My code looks like this:

public interface Hello extends Remote {
public String sayHello() throws RemoteException;
public void shutdown() throws RemoteException;
}

public class ServerTest implements Hello {
public static void main(String args[]) throws RemoteException,
AlreadyBoundException {
ServerTest obj = new ServerTest();

Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);

Registry registry = LocateRegistry.createRegistry(2001);

registry.rebind("hello", stub);
}

public String sayHello() throws RemoteException {
return "Hello there";
}

public void shutdown() throws RemoteException {
System.exit(0); // Other than doing something as violent as
this?????????????
}
}

public class ClientTest {
public static void main(String args[]) throws RemoteException,
NotBoundException {
Registry registry = LocateRegistry.getRegistry(2001);

Hello hello = (Hello)registry.lookup("hello");

System.out.println("stub.sayHello returns "+hello.sayHello());

hello.shutdown();
}
}

I am looking for a call like:

registy.shutdownInOrderlyFashion();

* Why does rmiregistry need to have access to the class definitions of
the interfaces?

The alternative way of doing the above is to run the rmiregisty
program seperately and get the registry by:

LocaleRegistry.getRegistry();

This works *only* if I start the rmiregistry program at the root of
generated class files; presumably because the rmiregistry program
needs to have access to the class definition of "Hello".

While I get that can define a codebase or classpath to point
elsewhere, I don't get why the rmiregistry program needs to have
access to the class definitions?

I as understand it, the rmiregistry simply should register the name
"hello" for the server and resolve the name "hello" as a reference to
something on the server for the client.

Only the client and the server should need to know the interface
definition.

-- Christian
 
E

Esmond Pitt

Christian said:
* Is there a clean way to shutdown a registry created locally in the
server code?

Yes. Unexport it. Make sure you keep the Registry reference returned by
LocateRegistry.createRegistry, then you can just pass that to
UnicastRemoteObject.unexportObject().

* Why does rmiregistry need to have access to the class definitions of
the interfaces?

Because it receives the stub via an RMI call. That means that it has to
be able to deserialize the stub, and to deserialize the stub it needs
the remote interfaces, and the closure of any other application classes
the remote interface depends on.
I as understand it, the rmiregistry simply should register the name
"hello" for the server and resolve the name "hello" as a reference to
something on the server for the client.

It doesn't do that. It resolves the name as a remote stub which it is
holding in its own JVM space (in a Map<String, Remote>). The stub in
turn contains stuff that refers to the remote server object, i.e. its
{IP, port}, its objectID.
 
C

Christian Hvid

Yes. Unexport it. Make sure you keep the Registry reference returned by
LocateRegistry.createRegistry, then you can just pass that to
UnicastRemoteObject.unexportObject().

I did a bit of experimenting - this does not work:

private static Registry registry;

....

registry = LocateRegistry.createRegistry(2001);

....

public void shutdown() throws RemoteException {
UnicastRemoteObject.unexportObject(registry, true);
}

But this did:

public void shutdown() throws RemoteException {
UnicastRemoteObject.unexportObject(this, true);
}

Maybe that was what you meant?

Anyway; what are good (simple) design practices for a basic RMI
application like this?

Is creating the registry as in the example ok or is there some other
approach I should look at?
 
E

Esmond Pitt

Christian said:
Maybe that was what you meant?

No, it isn't what I meant. The former does indeed work subject to what I
said: 'registry' must be the value returned by
LocateRegistry.createRegistry() (because that is the actual Registry
remote object). If it has subsequently become the value returned by
LocateRegistry.getRegistry() it won't work (because that is a Registry
stub).
Is creating the registry as in the example ok or is there some other
approach I should look at?

I prefer creating the Registry inside the server JVM if possible: that
way you avoid a number of headaches such as the shutdown problem and the
Registry classpath problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,968
Messages
2,570,150
Members
46,697
Latest member
AugustNabo

Latest Threads

Top