Potential infinite waiting at JMXConnection#createConnection

KUBOTA Yuji kubota.yuji at gmail.com
Wed May 6 10:43:12 UTC 2015


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.jiang at 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.jiang at 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.yuji at 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();
> >
> >
> >
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/serviceability-dev/attachments/20150506/15f9784a/attachment-0001.html>


More information about the serviceability-dev mailing list