Hi Shanliang, Many thanks for your help!
I do not have any role yet. So I can not create a new bug at JBS. It's a reason why I submitted a mail with my patch at first. This issue is caused by a rare network problem during the flush() [3] . I got this infinite loop only once. So I will try to write test or/and client codes with BCI for reproduction. Thanks, Yuji 2015-05-06 18:51 GMT+09:00 Shanliang Jiang <shanliang.ji...@oracle.com>: > Hi Yuji, > > I think better at first to create a bug at: > https://bugs.openjdk.java.net/secure/Dashboard.jspa > > It looks like an issue for me, it must be possible to have a test to > reproduce the issue. It is helpful to attach the test and present your > solution in the bug. > > I can help if you need any help to create the bug. > > Shanliang > > > > KUBOTA Yuji wrote: > > My apologies for re-post, I forgot to register serviceability-dev before > the last post. > > Hi Shanliang, > > Thanks you for your help! > > RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE is a nice workaround. > > However, many users believe sun.rmi.transport.tcp.responseTimeout > to specify the timeout, > e.g. the second flush() of TCPChannel#createConnection [2]. > In really, the first flush() [3] is not affected by > sun.rmi.transport.tcp.responseTimeout, > and will be the (potential) infinite waiting by bad luck. So I think > openjdk should fix it for users. > > [2]: > http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/c5b5d9045728/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java#l296 > [3]: > http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/c5b5d9045728/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java#l227 > > Thanks, > Yuji > > 2015-05-05 2:03 GMT+09:00 Shanliang Jiang <shanliang.ji...@oracle.com>: > > Hi Yuji, > > > > (I reply to serviceability alias) > > > > When you create a RMI server connector, you can specify a > > RMIClientSocketFactory by RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, this > allows > > you to specify your SoTimeout. > > > > Hope this helps. > > > > Shanliang > > > > > > > > KUBOTA Yuji wrote: > > > > 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(); > > > > > > > > >