# Java6 - RMI - "SocketTimeoutException: Accept timed out



## xsare (4. Aug 2008)

Hallo Zusammen,

ich bin gerade dabei eine Anwendung in der auch RMI verwendet wird, von Java 1.4 auf Java 6 umzustellen.
Nach der Umstellung treten jedoch, nach der Verbindungsherstellung (Client zum Server) WARNUNGen aus der RMI-Schicht im Server auf. 
Die Warnung erschein zyklisch, ca. jede Minute einmal.


```
04.08.2008 08:56:48 sun.rmi.transport.tcp.TCPTransport$AcceptLoop executeAcceptLoop
WARNUNG: RMI TCP Accept-0: accept loop for ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=1198] throws
java.net.SocketTimeoutException: Accept timed out
	at java.net.PlainSocketImpl.socketAccept(Native Method)
	at java.net.PlainSocketImpl.accept(Unknown Source)
	at java.net.ServerSocket.implAccept(Unknown Source)
	at java.net.ServerSocket.accept(Unknown Source)
	at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(Unknown Source)
	at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
```

Unter Java 1.4 trat diese Meldung nicht auf. Die Meldung führt zu keinen weiteren Problemen.

Hat jemand schon einmal so etwas gehabt, oder weis jemand wie man die Meldung eliminieren kann?

Mit freunlichem Gruß,
xsare


----------



## tuxedo (4. Aug 2008)

Ein wenig seltsam ist das schon. So wie ich das verstehe wartet der auf eine eingehende Verbindung nur eine bestimmte Zeit lang. Da er aber in einer Schleife wartet, wartet er nach dem TimeOut wieder von vorne. Die Fehlermeldung ist nicht tragisch, nur eben sehr unschön. "Umgehen" könnte man das, indem man das TimeOut "abschaltet". Dann bricht er beim warten nicht ab, sondern wartet wirklich solange auf einen Client, bis einer daherkommt.

Ein TimeOut auf RMI hab ich noch nicht eingestellt, aber hast du mal nach "rmi accept timeout" gegoogelt?

- Alex


----------



## xsare (4. Aug 2008)

Hallo, bei Google habe ich nichts gefunde, aber im Quellcode   :wink: 

Im Code ist eine eigene RMISocketFactory implemeniert, welche dem ServerSocket einen Timeout setzt.

```
ServerSocket temp = new ServerSocket(...);
            temp.setSoTimeout(socketTimeout);
```

Lässt man diesen Timeout weg, so tritt die Warnung nicht mehr auf.

Seltsam ist nur:
1. ... dass ich noch keinen Zusammenhang zwischen der Timout-Zeit und dem zeitlichen Auftreten der Warnung entdecken konnte. Es treten immer alle ca. 30 s zwei aufeinanderfolgende Warnungen auf. Unabhängig vom gesetzten SoTimeout.
Selbst wenn der SoTimeout auf 0 gestellt wird (laut API: "A timeout of zero is interpreted as an infinite timeout.") tritt die Warnung auf.
Ruft man nach dem Setzen des SoTimeout den gesetzten Wert mit getSoTimeout() ab, so liefert er erstaunlicherweise immer 30000 (30s). Auch wenn man 0 gesetzt hat.
2. ... dass das Problem mit Java 1.4 nicht auftritt.


----------



## tuxedo (8. Aug 2008)

Wie und wo setzt du denn das Timeout? Hast du überhaupt zugriff von außen auf die RMI internas?

- Alex

p.s. ich weiß schon warum ich RMI nicht (mehr) mag.


----------



## xsare (8. Aug 2008)

Mir ist da leider ein Fehler unterlaufen. Der Timeout wird korrekt gesetzt, und hat auch die gewünschte Auswirkung.


----------



## tuxedo (8. Aug 2008)

Verrätst du jetzt noch wie das geht? Dann haben andere auch was davon...

- Alex


----------



## xsare (8. Aug 2008)

Verbindungsherstellung:

```
...
MyRmiSocketFactory socketFactory = new MyRmiSocketFactory(RMI_SOCKET_SOTIMEOUT);
registry = LocateRegistry.createRegistry(getPort(), socketFactory, socketFactory);
registry.bind(Foo.LOOKUP_NAME, new FooImpl());
...
```

Setzen des Timeouts in der SocketFactory:

```
public static class MyRmiSocketFactory extends RMISocketFactory
    {
    //....
    //Einiges an Code....
    //.....

      public ServerSocket createServerSocket(int port) throws IOException
        {
            ServerSocket temp = new ServerSocket(port, m_SocketBacklog);
            temp.setSoTimeout(m_SocketTimeout);
            return temp;
        }

          public Socket createSocket(String host, int port) throws IOException
        {
            Socket temp = new Socket(host, port);
            temp.setSoTimeout(m_SocketTimeout);
            return temp;
        }

      //... das wars auch schon
}
```

Also im Endeffekt ist der springende Punkt die Verwendung einer eigenen SocketFactory, welche auch schon in einem früheren Post von mir erwähnt ist.


----------

