Hi Roger,

Thank you for reviewing. File bug: https://bugs.openjdk.java.net/browse/JDK-8170728

-Hamlin


On 2016/12/5 22:31, Roger Riggs wrote:
Hi Hamlin,

The changeset looks fine (to use /othervm).

Please file a new issue for your finding about createRegistry(0); I agree it is likely a product issue.

Thanks, Roger


On 12/5/2016 3:12 AM, Hamlin Li wrote:
Would you please review the below patch?

bug: https://bugs.openjdk.java.net/browse/JDK-8170669
webrev: http://cr.openjdk.java.net/~mli/8170669/webrev.00/

Root Cause:
2 tests impact each other. (test/com/sun/jndi/rmi/registry/RegistryContext/ContextWithNullProperties.java, UnbindIdempotent.java)
Solution:
adding othervm should resolve the issue.

Thank you
-Hamlin


p.s. Besides of the test issue talked above, I think there is some defect in RMI API, below is the analysis.

Root Cause:
when calling LocateRegistry.createRegistry(port), it will check if the ObjectTable contains the same ObjectEndPoint, if it contains, "java.rmi.server.ExportException: internal error: ObjID already in use" is thrown in ObjectTable.java. 2 ObjectEndPoint objects are considered the same if both have the same id and same tranport instance. For 2 calls of LocateRegistry.createRegistry(0), they have the same id(ObjID.REGISTRY_ID) and same endpoint & transport instance, so they are considered the same and exception is thrown.

================= more detailed explanation =================
Although in LocateRegistry.createRegistry(0)->...->TCPTransport->exportObject(target)->TCPTransport.listen()->TCPEndpoint.setDefaultPort(...), it will add new endpoint instance for port 0 with a specific port number(for example, it's 9999) in localEndpoints, but it still keeps endpoint instance for port 0 in localEndpoints, and both endpoints(0, 9999) are mapped to the same epList which includes one item with port number as 9999. the transport member of previous 2 endpoint instances(0, 9999) is indeed built on port 9999, this transport listening on port 9999 is used as part of key(other part is object id) to insert into ObjectTable. so when LocateRegistry.createRegistry(0) is called second time, LocateRegistry.createRegistry(0)->...->TCPEndpoint.getLocalEndpoint(0, ...) will get the previous transport instance(listening on 9999), so finally, in LocateRegistry.createRegistry(0)->...->ObjectTable.putTarget(target), in line 183 of ObjectTable.java, objTable.containsKey(oe) will return true, then exception is thrown.

================= conclusion =================
I think this is a RMI product issue, because below code runs successfully,
        Registry registry1 = LocateRegistry.createRegistry(60003);
        Registry registry2 = LocateRegistry.createRegistry(60004);
but below code will throw exception,
        Registry registry1 = LocateRegistry.createRegistry(0);
        Registry registry2 = LocateRegistry.createRegistry(0);



Reply via email to