KUBOTA Yuji wrote:
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.
To reproduce the bug, I was thinking to use RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE to specify a user socket server, which will not response any client connection request, I did not yet test this solution.

Shanliang

Thanks,
Yuji

2015-05-06 18:51 GMT+09:00 Shanliang Jiang <shanliang.ji...@oracle.com <mailto: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 <mailto: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
    <mailto: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();
> >
    >




Reply via email to