Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient Connection pool shut down

I am using HttpClient v4.5.5

I have an HttpClient as below:

PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
    connManager.setMaxTotal(totalMaxConnections);
    connManager.setDefaultMaxPerRoute(defaultMaxConnPerRoute);
CloseableHttpClient httpClient =HttpClients.custom().setConnectionManager(connManager).setConnectionManagerShared(true).build();

Then I use the http client as below:

protected Response connect(final Function<AbstractHttpAdapter, CloseableHttpResponse> pcAction) {
    Response response = null;
    final Instant begin = Instant.now();
    try {
        final CloseableHttpResponse closableResp = pcAction.apply(this);
        try {
            final Instant end = Instant.now();
            if (closableResp != null) {
                final HttpEntity responseEntity = closableResp.getEntity();
                if (responseEntity != null) {
                    response = new Response();
                    InputStream is = responseEntity.getContent();
                    try {

                        final ContentType contentType = ContentType.getOrDefault(responseEntity);
                        Charset charset = contentType.getCharset();
                        if (charset == null)
                            charset = Charset.forName("UTF-8");
                        response.responseText = IOUtils.toString(is, charset.toString());
                        if (closableResp.getStatusLine() != null) {
                            response.statusLine = closableResp.getStatusLine();

                        }
                        Map<String, String> responseHeaders = new HashMap<>();
                        Header[] headers = closableResp.getAllHeaders();
                        for (Header h : headers) {
                            responseHeaders.put(h.getName(), h.getValue());
                        }
                        response.responseHeaders = responseHeaders;
                        response.responseDuration = Duration.between(begin, end).toMillis();
                    } catch (UnsupportedOperationException | IOException e) {
                        LOGGER.error("IO Error: [{}]", e.getMessage());
                        LOGGER.debug("IO Error: {}", e);
                        return null;
                    } finally {
                        is.close();
                    }
                }
            } else {
                LOGGER.debug("NULL CloseableHttpResponse!");
            }
        } finally {
            if (closableResp != null)
                closableResp.close();
        }
    } catch (IOException e) {
        LOGGER.error("IO Error: [{}]", e.getMessage());
        LOGGER.debug("IO Error: {}", e);
        response = null;
    } catch (Exception ex) {
        LOGGER.error("IO Error: [{}]", ex.getMessage());
        LOGGER.debug("IO Error: {}", ex);
        response = null;
    }
    return response;
}

public CloseableHttpResponse executePost(final URL url, final String request, final int connectTimeout,
        final int readTimeout, Map<String, String> extraHeaders) {

    LOGGER.trace("Executing post request...");
    CloseableHttpResponse closeableHttpResponse = null;
    final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
    final RequestConfig requestConfig = requestConfigBuilder.setSocketTimeout(readTimeout)
            .setConnectTimeout(connectTimeout).build();

    final URI uri = prepareUri(url, null);
    final HttpPost httpPost = new HttpPost(uri);
    try {
        httpPost.setEntity(new StringEntity(request, StandardCharsets.UTF_8));
        httpPost.setConfig(requestConfig);
        if (MapUtils.isNotEmpty(extraHeaders)) {
            for (Map.Entry<String, String> header : extraHeaders.entrySet()) {
                httpPost.setHeader(header.getKey(), header.getValue());
            }
        }
        closeableHttpResponse = httpClient.execute(httpPost, HttpClientContext.create());
    } catch (ClientProtocolException e) {
        LOGGER.error("HTTP Error for URL [{}] and RequestParams [{}]: {}", url, request, e);
    } catch (IOException e) {
        LOGGER.error("IO Error for URL [{}] and RequestParams [{}]: {}", url, request, e.getMessage());
        LOGGER.debug("IO Error for URL [{}] and RequestParams [{}]: {}", url, request, e);
    } catch (Exception e) {
        LOGGER.error("General Error for URL [{}] and RequestParams [{}]: {}", url, request, e);
    }
    return closeableHttpResponse;
}

calling connect via threadPoolTaskScheduler periodically (every few minutes)

Once in a while I get an error

java.lang.IllegalStateException: Connection pool shut down and from what I have read this happens either with older HttpClient version or when you close the HttpClient. Which I do not do. So I cannot understand why I get this error. It recovers but it is a problem having exceptions like that.

like image 806
idipous Avatar asked Nov 08 '22 10:11

idipous


1 Answers

got same error but finally solved. this error caused that i use the try () {} as below:

try (PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager()) {
                manager.setMaxTotal(600);
                manager.setDefaultMaxPerRoute(100);

this construction will auto close resources.

class:PoolingHttpClientConnectionManager exist a method as below:

 public void close() {
        this.shutdown();
    }

finally will invoke close().

like image 184
Joy Avatar answered Nov 15 '22 04:11

Joy