JDK-6269166 : change in sun.rmi.transport.tcp.TCPEndpoint.class breaks atg
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.rmi
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2005-05-12
  • Updated: 2006-05-04
  • Resolved: 2005-06-06
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 betaFixed
Related Reports
Relates :  
Description
One of bigapps, atg, is broken by recent change in sun.rmi.transport.tcp.TCPEndpoint.class

the same test passed with mustang b35, but failed with  mustang b36.

Before test starts, "netstat -n -a" shows port 8860 is NOT in use by any process.
But atg's rmiserver can not start, it complains that "port 8860" is in use.
Error message:
**** Error      Wed May 11 17:41:25 PDT 2005    1115858485010   /atg/dynamo/serv
er/RmiServer    Service /atg/dynamo/server/RmiServer unable to start server list
ening on port 8860java.rmi.server.ExportException: Port already in use: 8860; ne
sted exception is:
**** Error      Wed May 11 17:41:25 PDT 2005    1115858485010   /atg/dynamo/serv
er/RmiServer            java.net.BindException: Address already in use

How to reproduce the failure:
1. log to jtg-sunfire-4.sfbay ( contact ###@###.### for root passwd )
2. export JAVA_HOME=<your java home>
3. cd /scratch/atgrun
4. execute the script "run.server"
error message will be found in the output. 
The errors complains that port 8860 is in use.

if JAVA_ARGS is set to -Xbootclasspath/p:/tmp/mustang_b35, the test passes. 
# ls -lR /tmp/mustang_b35
/tmp/mustang_b35:
total 8
drwxr-xr-x   3 root     root         177 May 11 18:48 sun

/tmp/mustang_b35/sun:
total 8
drwxr-xr-x   3 root     root         183 May 11 18:48 rmi

/tmp/mustang_b35/sun/rmi:
total 8
drwxr-xr-x   3 root     root         177 May 11 18:48 transport

/tmp/mustang_b35/sun/rmi/transport:
total 8
drwxr-xr-x   2 root     root         270 May 11 18:48 tcp

/tmp/mustang_b35/sun/rmi/transport/tcp:
total 32
-rw-r--r--   1 root     root        2035 May 11 18:48 TCPEndpoint$FQDN.class
-rw-r--r--   1 root     root       10470 May 11 18:48 TCPEndpoint.class



###@###.### 2005-05-12 01:54:04 GMT

Comments
EVALUATION The class sun.rmi.transport.tcp.TCPEndpoint was recently changed in Mustang as part of the fix for 4457683. ###@###.### 2005-05-13 06:59:29 GMT From running the test application with an instrumented RMI implementation, it appears that the application undertakes the following steps: (1) Sets the global RMISocketFactory (using RMISocketFactory.setFactory) to an instance of a socket factory class (atg.server.rmi.DefaultPortRMISocketFactory) that implements the createServerSocket method to forward to the default global socket factory (returned by RMISocketFactory.getDefaultSocketFactory) with the added behavior that if the port argument is zero (indicating an anonymous port), it is replaced with a different value determined at construction time. In this case, this value is 8860. (2) Exports several remote objects using the static method UnicastRemoteObject.exportObject(Remote,int), passing 0 as the port value, indicating an anonymous port at this level of API-- but the global socket factory described above will convert this port choice to 8860, so TCP port 8860 will be bound for listening. (3) Attempts to create a registry using the static method LocateRegistry.createRegistry(int), passing 8860 as the port value. This last step fails with an ExportException because TCP port 8860 is already bound by another server socket: the one created for step (2). Since the fix for 4457683, the RMI runtime does not make any connection between an earlier remote object export for an anonymous port that resulted in binding actual port X (2) and a later attempt to export a remote object specifially (non-anonymously) for port X (3). This sort of sequence of events is not normally expected to occur in an RMI application-- it only occurs with this application because of the installed socket factory that alters the meaning of exporting on an anonymous port to effectively exporting on a non-anonymous port instead. (Essentially, this application is combining two different approaches for exporting on a specific port.) The fact that the above sequence of events worked prior to the 4457683 fix was a largely unintended (and undocumented) consequence of the way that the RMI implementation was coded. Unfortunately, it is much more difficult to conceive of supporting that sequence of events along with a fix for 4457683, because with the possibility of freeing unused ports, resources for (seemingly) anonymous and non-anonymous port remote object exports that had been sharing a port would have to get separated cleanly. Offhand, supporting this old behavior along with a fix for 4457683 would seem to require non-trivial internal implementation rearchitecture. ###@###.### 2005-05-13 23:49:23 GMT Even though the kinds of usage of the RMI API that are required to encounter the change in behavior represented by this bug are not intended/documented to work (or even recommended-- note that if steps (2) and (3) above are reversed, a seemingly innocuous reordering, a BindException would occur anyway, even without this "bug"), it seems important to keep them working in order to avoid breaking existing applications, especially given that they have worked since JDK 1.1. For now, we are fixing this bug by partially undoing the fix for 4457683: a server socket created for exporting remote objects will only be closed (when no remote object remain exported on it) if it was originally created for an export on a non-anonymous (non-zero) port (which is presumably covers the most important cases for 4457683 anyway). A server socket originally created for an export on an anonymous port (which is required to encounter this bug-- as far as RMI is concerned, an anonymous port is used in the above steps, even if the socket factory transforms it to an explicit port) will not be closed while the VM remains alive, as was the longstanding behavior before the 4457683 fix. This compromise avoids for now the implementation complication of both supporting the behavior required to fix this bug and the complete 4457683 fix; a separate bug will be filed for completing the fix for 4457683 later. ###@###.### 2005-06-03 02:26:41 GMT
13-05-2005