JDK-4188333 : Cannot create new registry: Object ID already in use
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.rmi
  • Affected Version: 1.2.0
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_nt
  • CPU: x86
  • Submitted: 1998-11-09
  • Updated: 1998-12-23
  • Resolved: 1998-12-23
Related Reports
Relates :  
Description

Name: tb29552			Date: 11/09/98


/*
I reported this bug against 1.1.7 and 1.2beta4,
and it was assigned to bug 4120329 which was
supposed to be fixed in 1.2fcs.  That bug did get
fixed, but the bug as I described it did not.
So here it is again...


Here's an RMI and/or garbage collection problem.

This test program program creates a registry.  Then it
tries to remove it with garbage collection so it can
make another one.  This exception is thrown:

java.rmi.server.ExportException: Object ID already in use

Why doesn't garbage collection take care of this?

And if it doesn't, why isn't their a method like
java.rmi.registry.LocateRegistry.removeRegistry()?
*/
/*
This problem also exists across JVMs.  If program1
"creates" the registry, program2 can "get" the
registry.  But if program1 disappears, program2
cannot "create" another registry.  It says the object
ID is in use even though program1 that created it is
gone.  Also, if program2 tries to "get" the registry
again after program1 is gone, it works with no
exception.  But this is a bogus registry and it
fails when trying to use it (e.g. bind).

And yes, I really want to do this.  I want to have
registries be created by whoever needs them if
their current registry goes away.

Here's the code:

*/
import java.rmi.registry.*;

class RegistryTest  {
    public static void main(java.lang.String[] args)
    {
        Registry reg = null;
        try
        {
            System.out.println("creating registry");
            reg = LocateRegistry.createRegistry(1099);
            System.out.println("created registry");
        }
        catch(Exception e)
        {
            System.out.println("cannot create registry");
            e.printStackTrace();
        }
        System.out.println("removing registry");
        reg = null;
        System.gc();
        try
        {
            System.out.println("creating another registry");
            reg = LocateRegistry.createRegistry(1099);
            System.out.println("created another registry");
        }
        catch(Exception e)
        {
            System.out.println("cannot create another registry");
            e.printStackTrace();
        }
    }
}


(Review ID: 42355)
======================================================================

Comments
WORK AROUND The following code demonstrates how the method java.rmi.server.UnicastRemoteObject.unexport(Remote obj) may be used to cause the registry to be garbage collected: Registry registry = java.rmi.registry.LocateRegistry.createRegistry(1099); UnicastRemoteObject.unexportObject((Remote) registry, true); System.err.println("registry unexported"); registry = java.rmi.registry.LocateRegistry.createRegistry(1099); System.err.println("registry reexported");
11-06-2004

PUBLIC COMMENTS The RMI registry remote object is one of a few remote objects (currently three) that have well known objects IDs. Because the registry has a well-known object id, it is possible for clients to create their own remote references to the registry (i.e. bootstrap). The java.rmi.Naming class performs this task. This special characteristic of the registry means that the object may have unknown clients which intend to use the registry but which are not participating in distributed garbage collection (i.e. have not yet made a remote call to the registry). If RMI were to treat the registry similar to other remote objects, the registry might be collected even though some clients expected to use the object. In order to make the registry service more reliable, the RMI runtime "pins" its implementation object with a strong local reference so that the registry will never be garbage collected for the life of the registry JVM. In JDK1.2, there is a simple way to change the above behavior (provided that a given application wants the registry object to be garbage collected). The following code demonstrates how the method java.rmi.server.UnicastRemoteObject.unexport(Remote obj) may be used to cause the registry to be garbage collected: Registry registry = java.rmi.registry.LocateRegistry.createRegistry(1099); UnicastRemoteObject.unexportObject((Remote) registry, true); System.err.println("registry unexported"); registry = java.rmi.registry.LocateRegistry.createRegistry(1099); System.err.println("registry reexported"); Unfortunately, in jdk 1.1.x, there is no method to unexport a remote object. Therefore since the registry already is running in the local VM, you can not bring it down until you stop the current VM. The lack of an "unexport" method in JDK1.1 was merely an oversight that has been fixed in 1.2.
10-06-2004

EVALUATION This is not a bug but merely the way RMI is intended to function, see Public summary. lairdd@east 1998-12-23
23-12-1998