Hi all, I want to contribute this issue. If there are a problem about this patch or a better way for openjdk community, please advise me.
Thanks for 2015-04-22 0:31 GMT+09:00 KUBOTA Yuji <kubota.y...@gmail.com>: > Hi all, > > I found an infinite waiting at TCPChannel#createConnection. > This method flushes the DataOutputStream without the socket timeout settings > when choose stream protocol [1]. > > If connection lost (the destination server do no return response) > during the flush, > this method has possibilities to take long time beyond the expectations > at java.net.SocketInputStream.socketRead0 as following stack trace. > > stack trace : > at java.net.SocketInputStream.socketRead0(SocketInputStream.java) > at java.net.SocketInputStream.read(SocketInputStream.java) > at java.net.SocketInputStream.read(SocketInputStream.java) > at sun.security.ssl.InputRecord.readFully(InputRecord.java) > at sun.security.ssl.InputRecord.read(InputRecord.java) > at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java) > at > sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java) > at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java) > at sun.security.ssl.AppOutputStream.write(AppOutputStream.java) > at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java) > at java.io.BufferedOutputStream.flush(BufferedOutputStream.java) > at java.io.DataOutputStream.flush(DataOutputStream.java) > at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java) > at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java) > at sun.rmi.server.UnicastRef.invoke(UnicastRef.java) > at javax.management.remote.rmi.RMIServerImpl_Stub.newClient > at > javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java) > at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java) > at > javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java) > > When create connection, we cannot set the timeout by properties. > Therefore, JMX sets the default value of SO_TIMEOUT, i.e., infinite. > So I wrote a patch to fix this infinite waiting by using property-configured > value: > sun.rmi.transport.tcp.responseTimeout. > > Please review this patch. :) > > Note: My OCA has been processed a few hour ago, so my name may take a > short time to > appear on the OCA signatories page. > > Thanks, > KUBOTA Yuji > > [1]: > http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/c5b5d9045728/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPConnection.java#l191 > > diff --git a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java > b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java > --- a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java > +++ b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java > @@ -222,20 +222,34 @@ > // choose protocol (single op if not reusable socket) > if (!conn.isReusable()) { > out.writeByte(TransportConstants.SingleOpProtocol); > } else { > out.writeByte(TransportConstants.StreamProtocol); > + > + int usableSoTimeout = 0; > + try { > + /* > + * If socket factory had set a zero timeout on its > own, > + * then set the property-configured value to prevent > + * an infinite waiting. > + */ > + usableSoTimeout = sock.getSoTimeout(); > + if (usableSoTimeout == 0) { > + usableSoTimeout = responseTimeout; > + } > + sock.setSoTimeout(usableSoTimeout); > + } catch (Exception e) { > + // if we fail to set this, ignore and proceed anyway > + } > out.flush(); > > /* > * Set socket read timeout to configured value for JRMP > * connection handshake; this also serves to guard > against > * non-JRMP servers that do not respond (see 4322806). > */ > - int originalSoTimeout = 0; > try { > - originalSoTimeout = sock.getSoTimeout(); > sock.setSoTimeout(handshakeTimeout); > } catch (Exception e) { > // if we fail to set this, ignore and proceed anyway > } > > @@ -279,18 +293,11 @@ > * connection. NOTE: this timeout, if configured to a > * finite duration, places an upper bound on the time > * that a remote method call is permitted to execute. > */ > try { > - /* > - * If socket factory had set a non-zero timeout on > its > - * own, then restore it instead of using the > property- > - * configured value. > - */ > - sock.setSoTimeout((originalSoTimeout != 0 ? > - originalSoTimeout : > - responseTimeout)); > + sock.setSoTimeout(usableSoTimeout); > } catch (Exception e) { > // if we fail to set this, ignore and proceed anyway > } > > out.flush();