JDK-8004087 : rmi connection should be closed explicitly in catch(Exception) clause
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.rmi
  • Affected Version: 7u9
  • Priority: P3
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: windows_2008
  • CPU: x86
  • Submitted: 2012-11-28
  • Updated: 2017-05-05
  • Resolved: 2017-05-05
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.
Other
tbd_majorResolved
Related Reports
Relates :  
Description
In the following src portion of DGCClient.java, 

---- jdk7u9/jdk/src/share/classes/sun/rmi/transport/DGCClient.java ---
...
    652         /**
    653          * Make all of the clean calls described by the clean requests in
    654          * this entry's set of "pending cleans".  Clean requests for clean
    655          * calls that succeed are removed from the "pending cleans" set.
    656          *
    657          * This method must NOT be called while synchronized on this entry.
    658          */
    659         private void makeCleanCalls() {
    660             assert !Thread.holdsLock(this);
    661
    662             Iterator iter = pendingCleans.iterator();
    663             while (iter.hasNext()) {
    664                 CleanRequest request = (CleanRequest) iter.next();
    665                 try {
    666                     dgc.clean(request.objIDs, request.sequenceNum, vmid,
    667                               request.strong);
    668                     iter.remove();
    669                 } catch (Exception e) {
    670                     /*
    671                      * Many types of exceptions here could have been
    672                      * caused by a transient failure, so try again a
    673                      * few times, but not forever.
    674                      */
    675                     if (++request.failures >= cleanFailureRetries) {
    676                         iter.remove();
    677                     }
    678                 }
    679             }
    680         }
.....

--------

when rmi connection(dgc.clean()) completes and then exceptions(other than ConnectionException) occur, the connection seem still alive in "catch" clause.

Furthermore, in "while()" loop, the above mentioned flow (dgc.clean() and exception) is iterated(re-tried),
a lot of rmi connections(resources) remain.
It seems that the rmi connections should be closed explicitly in catch(Exception) clause.
(or in a timely manner)

Comments
No activity on this for a couple years. The information in the bug is rather confused and describes several different problems, but the primary assertion that the connection should be closed at a certain point is incorrect. Closing as Cannot Reproduce.
05-05-2017

I could only reproduce it on RHEL (reproducing on anything else is still in my TODO list). I guess these issues were connected together only because of the stack trace similar to the one above. I don't really see how the suggestion to close the connection in the catch clause would help. The observed problem is that the new redundant connections are opened. If I'm not mistaken, the exception isn't thrown here.
08-10-2014

Is this only on RHEL, or was it on some other platform? Does this have anything to do with the original suggestion to close the connection in the catch clause, or is it independent?
08-10-2014

Closing the connections from the makeCleanCalls() method doesn't seem correct. This section of code deals with object references and maintenance of state associated with distributed garbage collection (DGC), which is basically time-based leases and reference counting. This is orthogonal to TCP connections. It is possible for a client's reference to a remote object to outlive a particular TCP connection. Alternatively, a DGC request may result in an exception occurring, for example, because the remote object might be unexported while clients still have references to it. If this occurs, closing the connection in use may unnecessarily disrupt communications between other objects that happen to be sharing the same connection. If excess connections are building up unnecessarily, the cause of this needs to be isolated and a fix applied, but this is probably in a different part of the RMI code.
02-09-2014

Temporarily assigning to you, I assume you will evaluate and assign/close as appropriate
04-04-2013

Additional inf. : - Connection is completed AND - Because an exception(ex. "read" timeout because of no response) occurs during client and server is communicating, communication can not be done correctly. In the above case, the connenction should be closed explicitly. According to further investigation, current JDK6 works as follows. (1) Communication is done correctly When communication is cached, re-used and then finished, JDK6 closes the connection explicitly. (2) Fail to establish connection Because the connection itself is not completed, "close" operation is not needed. (3) Connection is completed, communication can not be done(case1) A new connection is completed in TCPChannel#newConnection(). When an exception occurs in hand-shake operation and communication can not be done, JDK6 DOES NOT close the connection explicitly. (4) Connection is completed, communication can not be done(case2) When the hand-shake operation in the above (3) is completed, but an exception occurs in remote method call and communication can not be done, JDK6 closes the connection explicitly. The "close" operation in the above (3) is not done in the current JDK6. (This is related to the implementation in UnicastRef class and TCPChannel class.)
03-12-2012