JDK-4457683 : port used by remote object is not freed up after remote object is unexported
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.rmi
  • Affected Version: 1.0,1.1,1.4.0,5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS:
    generic,linux_redhat_3.0,solaris_2.6,solaris_7 generic,linux_redhat_3.0,solaris_2.6,solaris_7
  • CPU: generic,sparc
  • Submitted: 2001-05-11
  • Updated: 2005-07-20
  • Resolved: 2005-05-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
Duplicate :  
Relates :  
Relates :  
Description
If a remote object is exported by a call to 
UnicastRemoteObject.exportObject(obj, port), and later unexported
by a call to UnicastRemoteObject.unexportObject(obj, true), the port is still
being used.

The following code shows the problem:

import java.rmi.registry.LocateRegistry;
import java.io.*;
import java.rmi.server.*;
import java.net.*;
import java.rmi.*;

public class ExportTest {        
    public static void main(String[] args) throws Exception {
        int port = 10001;
        ExpObj obj = (ExpObj) new ExpObjImpl();
        UnicastRemoteObject.exportObject(obj, port);        
        UnicastRemoteObject.unexportObject(obj, true);
        try {
            ServerSocket s = new ServerSocket(port);
        } catch (IOException e) {
            System.out.println("Got an exception in creating ServerSocket");
            e.printStackTrace();
        }            
    }
    
}

interface ExpObj extends java.rmi.Remote {    
}

class ExpObjImpl implements ExpObj {
    public ExpObjImpl() throws RemoteException {}
}

The output is:

Got an exception in creating ServerSocket
java.net.BindException: Address already in use
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:397)
        at java.net.ServerSocket.<init>(ServerSocket.java:170)
        at java.net.ServerSocket.<init>(ServerSocket.java:82)
        at ExportTest.main(ExportTest.java:14)

Comments
WORK AROUND It is possible (but very ugly) to use an RMI socket factory to actually close but mislead RMI into "believing" that the socket is still open. An application can use a specialized "protocol" to inform custom socket factories when their associated exported object implementations have been unexported. At such time, the socket factory can call close on the socket instance it is wrapping. ---------- See an example of the above-suggested workaround posted here: http://archives.java.sun.com/cgi-bin/wa?A2=ind0507&L=rmi-users&P=4036 ###@###.### 2005-07-20 21:01:00 GMT
20-07-2005

EVALUATION The RMI runtime should determine when ports are no longer in use (all objects unexported on that port, no calls in progress, etc.) so that it can close a server socket for an unused port. We should reconsider implementing this for tiger. ###@###.### 2002-07-16 This bug is under consideration for Tiger, at least for non-anonymous port bindings like in the example provided. (Incidentally, note that bound ports are, of course, freed if the entire virtual machine terminates.) ###@###.### 2003-07-10
10-07-2003