Uploaded image for project: 'HttpComponents HttpClient'
  1. HttpComponents HttpClient
  2. HTTPCLIENT-908

java.net.SocketException: Socket closed in org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:130)

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Cannot Reproduce
    • Affects Version/s: 4.0 Final
    • Fix Version/s: None
    • Component/s: HttpClient (classic)
    • Labels:
      None
    • Environment:

      Description

      I can't reproduce this in a controlled situation, but in my production environment I see about 400 of these per day:

      Caused by: java.net.SocketException: Socket closed
      at java.net.SocketInputStream.socketRead0(Native Method)
      at java.net.SocketInputStream.read(SocketInputStream.java:129)
      at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:130)
      at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:127)
      at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:161)
      at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:159)
      at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:173)
      at org.apache.http.impl.io.ContentLengthInputStream.close(ContentLengthInputStream.java:106)
      at org.apache.http.entity.BasicHttpEntity.consumeContent(BasicHttpEntity.java:142)
      at org.apache.http.conn.BasicManagedEntity.consumeContent(BasicManagedEntity.java:98)
      at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:767)
      at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:708)
      at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:699)

      From what I understand of "Socket closed", it means that we (httpclient likely) have locally closed the socket we are trying to read. I always get this same stacktrace.

      I construct my client like this:

      return new DefaultHttpClient(generateConnectionManager(params), params) {

      @Override
      protected BasicHttpProcessor createHttpProcessor() {
      final BasicHttpProcessor httpproc = new BasicHttpProcessor();
      httpproc.addInterceptor(new RequestDefaultHeaders());
      // Required protocol interceptors
      httpproc.addInterceptor(new RequestContent());
      httpproc.addInterceptor(new RequestTargetHost());
      // Recommended protocol interceptors

      /*

      • This one adds connection:keep-alive to the request, but we do not want that here.
      • If we are talking directly to a service instance it will reply without connection
      • control headers and with HTTP/1.0, which will cause it to close right away.
      • If we are going through the netscaler it adds a connection:keep-alive and we will
      • respect that.
      • httpproc.addInterceptor(new RequestClientConnControl());
        */
        httpproc.addInterceptor(new RequestUserAgent());
        httpproc.addInterceptor(new RequestExpectContinue());
        // HTTP state management interceptors
        httpproc.addInterceptor(new RequestAddCookies());
        httpproc.addInterceptor(new ResponseProcessCookies());
        // HTTP authentication interceptors
        httpproc.addInterceptor(new RequestTargetAuthentication());
        httpproc.addInterceptor(new RequestProxyAuthentication());

      // https://issues.apache.org/jira/browse/HTTPCLIENT-883
      httpproc.addInterceptor(new HttpRequestInterceptor() {

      public void process(final HttpRequest request, final HttpContext context) throws HttpException,
      IOException

      { final HttpClientConnection conn = (HttpClientConnection) context .getAttribute(ExecutionContext.HTTP_CONNECTION); final int timeout = request.getParams().getIntParameter(CoreConnectionPNames.SO_TIMEOUT, 0); conn.setSocketTimeout(timeout); }

      });

      return httpproc;
      }

      };

      and the connection manager is generated like this:

      final SchemeRegistry schemeRegistry = generateSchemeRegistry();

      /*

      Field tmp = null;
      try

      { tmp = SocketHttpClientConnection.class.getDeclaredField("open"); }

      catch (final Exception e)

      { log.fatal("...", e); Shutdown.shutdown(-1); }

      final Field openField = tmp;
      openField.setAccessible(true);

      return new ThreadSafeClientConnManager(params, schemeRegistry) {

      @Override
      protected ClientConnectionOperator createConnectionOperator(final SchemeRegistry schreg) {
      return new DefaultClientConnectionOperator(schreg) {

      @Override
      public OperatedClientConnection createConnection() {
      return new DefaultClientConnection() {

      @Override
      public void close() throws IOException {
      if (!isOpen())

      { return; }

      try

      { openField.set(this, false); }

      catch (final Exception e)

      { // eat it }

      try {
      doFlush();
      try {
      try

      { getSocket().shutdownOutput(); }

      catch (final IOException ignore) {
      }
      try

      { getSocket().shutdownInput(); }

      catch (final IOException ignore) {
      }
      } catch (final UnsupportedOperationException ignore)

      { // if one isn't supported, the other one isn't either }

      } finally

      { getSocket().close(); }

      }
      };
      }
      };
      }

      };

      So I have a few patches in there, but this should be pretty similar to what is in 4.0.1. I do not have a repro case and inspection of the code did not reveal anything – I don't see a close(); read((;

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              dkoski David Koski
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: