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