title: Stucked Threads with Apache HTTP Client 4.5.x
body: <p>in my weblogic a lot of threads are stuck on this way, but I can't figure the reason. This is the stacktrace. I setted all timeouts of the connection:</p>
  
  <ul>
  <li>setConnectionRequestTimeout</li>
  <li>setConnectTimeout</li>
  <li>setSocketTimeout</li>
  </ul>
  
  <p>This is the stack trace, I don't see any problems with code (at the end of post) that can cause this stucks threads. Any idea about this?</p>
  
  <pre><code>&lt;22-May-2018 11.48.46 CEST&gt; &lt;Error&gt; &lt;WebLogicServer&gt; &lt;BEA-000337&gt; &lt;[STUCK] ExecuteThread: '36' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "616" seconds working on the request "Http Request Information: weblogic.servlet.internal.ServletRequestImpl@7567f23c[POST /aca/rest/servicesupport]
  ", which is more than the configured time (StuckThreadMaxTime) of "600" seconds in "server-failure-trigger". Stack trace:
      java.net.SocketInputStream.socketRead0(Native Method)
      java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
      java.net.SocketInputStream.read(SocketInputStream.java:170)
      java.net.SocketInputStream.read(SocketInputStream.java:141)
      org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
      org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
      org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:282)
      org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138)
      org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
      org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
      org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
      org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:165)
      org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
      org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
      org.apache.http.impl.execchain.MainClientExec.createTunnelToTarget(MainClientExec.java:473)
      org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:398)
      org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
      org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
      org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
      org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
      org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
      org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
      org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
      com.iberia.es.integration.FacadeSFIntegrationImpl.requestToken(FacadeSFIntegrationImpl.java:71)
  </code></pre>
  
  <p>This is the Class with the connection methods. I am using <strong>Apache http client 4.5.3</strong>:</p>
  
  <pre><code>public class FacadeSFIntegrationImpl implements FacadeSFIntegration {
  
  
      @Autowired
      @Qualifier("confResolver")
      ConfigurationResolver config;
  
      @Override
      public String requestToken(List&lt;IbEsNameAndValueDTO&gt; params, String url, Boolean proxyEnabled,
              Integer connectionRequestTimeout, Integer connectTimeout, Integer socketTimeout) {
  
          if (params != null &amp;&amp; !params.isEmpty() &amp;&amp; url != null) {
  
              try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
                  // Preparamos los parámetros
                  List&lt;NameValuePair&gt; httpParams = convertParams(params);
  
                  // Configuramos la llamada
                  RequestConfig httpConfig = configHttpRequest(proxyEnabled, connectionRequestTimeout, connectTimeout,
                          socketTimeout);
  
                  // Realizamos la llamada post
                  HttpPost post = new HttpPost(url);
                  post.setConfig(httpConfig);
                  post.setEntity(new UrlEncodedFormEntity(httpParams, "UTF-8"));
  
                  // Controlamos la respuesta
                  HttpResponse response = httpClient.execute(post);
                  int status = response.getStatusLine().getStatusCode();
                  if (status &gt;= 200 &amp;&amp; status &lt; 300) {
                      HttpEntity entity = response.getEntity();
                      return EntityUtils.toString(entity);
                  }
  
              } catch (UnsupportedEncodingException e) {
                  //LOG
              } catch (ClientProtocolException e) {
                  //LOG
              } catch (IOException e) {
                  //LOG
              }
          }
  
          return null;
      }
  
  
      private RequestConfig configHttpRequest(Boolean proxyEnabled, Integer connectionRequestTimeout,
              Integer connectTimeout, Integer socketTimeout) {
  
          Builder httpConfigBuilder = RequestConfig.custom();
  
          if (proxyEnabled) {
              String proxyUrl = config.getValue("proxy.host");
              String proxyPort = config.getValue("proxy.puerto");
  
              HttpHost proxy = new HttpHost(proxyUrl, Integer.valueOf(proxyPort));
              httpConfigBuilder.setProxy(proxy);
          }
  
          String connectionRequestTimeoutDefaultS = config.getValue("proxy.timeout.connectionRequest");
          httpConfigBuilder.setConnectionRequestTimeout((connectionRequestTimeout != null) ? connectionRequestTimeout
                  : Integer.valueOf(connectionRequestTimeoutDefaultS));
  
          String connectTimeoutDefaultS = config.getValue("proxy.timeout.connect");
          httpConfigBuilder.setConnectTimeout((connectTimeout != null) ? connectTimeout : Integer
                  .valueOf(connectTimeoutDefaultS));
  
          String socketTimeoutDefaultS = config.getValue("proxy.timeout.socket");
          httpConfigBuilder.setSocketTimeout((socketTimeout != null) ? socketTimeout : Integer
                  .valueOf(socketTimeoutDefaultS));
  
          return httpConfigBuilder.build();
      }
  
      private List&lt;NameValuePair&gt; convertParams(List&lt;IbEsNameAndValueDTO&gt; params) {
  
          List&lt;NameValuePair&gt; result = new ArrayList&lt;&gt;();
          for (IbEsNameAndValueDTO nameValue : params) {
              result.add(new BasicNameValuePair(nameValue.getName(), nameValue.getValue()));
          }
          return result;
  
      }
  
  }
  </code></pre>