RFR of JDK-8170669: com/sun/jndi/rmi/registry/RegistryContext/UnbindIdempotent.java fails after JDK-8153916

Hamlin Li huaming.li at oracle.com
Mon Dec 5 08:12:42 UTC 2016


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);



More information about the core-libs-dev mailing list