2

I use HttpClient (https://hc.apache.org/httpcomponents-client-4.5.x/index.html) to make many http calls back to back and in parallel. After running for a while, it gets this exception:

java.net.BindException: Address already in use: connect

I tried to closing everything I can see, but I must still miss something because it still has that error.

How to properly release connections to avoid this connection leak problem?

Here's the test case to reproduce the problem, running in Java8 on Windows:

public void test(String url) throws Exception {
    List<Thread> threads = new ArrayList<Thread>();
    for(int t=0; t<40; t++) {
        int tt = t;
        threads.add(new Thread(() -> {
            for(int i=0; i<Integer.MAX_VALUE; i++) {
                URI metadataUri;
                try {
                    metadataUri = new URI(url);
                } catch (Exception e1) {
                    e1.printStackTrace();
                    continue;
                }

                HttpPost httpRequest = new HttpPost(metadataUri);
                httpRequest.setEntity(new ByteArrayEntity( "abc".getBytes()));
                //httpRequest.addHeader("Connection", "close");

                CloseableHttpClient httpclient = HttpClients.custom().build();
                try {
                    CloseableHttpResponse metadataResponse2 = httpclient.execute(httpRequest);
                    metadataResponse2.close();
                } catch (ClientProtocolException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        httpRequest.completed();
                        httpRequest.releaseConnection();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    try {
                        httpclient.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                System.out.println("thread " + tt + " round " + i);
            }
        }));
    }

    for(Thread thread : threads) {
        thread.start();
    }
}
David
  • 141
  • 1
  • 7
  • that exception just means that *something* is using that port, not necessarily that *you're* using it.... – Roddy of the Frozen Peas Nov 13 '18 at 16:38
  • But this is client port, not server port right? My understand is client port is dynamically allocated some where in TCP/IP layer and should be closed when the connection is close. But apparently, HttpClient lib is not closing connections in the above test code, so after running fine for about 12,000 http requests, it starts throwing that exception. – David Nov 13 '18 at 16:48

1 Answers1

-1

Normally, a try with resource (see reference) should handle this:

            try (CloseableHttpClient httpclient = HttpClients.custom().build();
                CloseableHttpResponse metadataResponse2 = httpclient.execute(httpRequest)) {
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                httpRequest.completed();
                httpRequest.releaseConnection();

            }
maio290
  • 6,440
  • 1
  • 21
  • 38
  • Thanks maio290! I tried that too, but still it doesn't help. – David Nov 13 '18 at 16:41
  • @David - how many rounds do you need to get this error? I added the metadataResponse2 to the try as well and don't have any error after ~ 1000 rounds. – maio290 Nov 13 '18 at 16:43
  • I just did that too, and consistently got the error after about 400 rounds on each of those 40 threads. – David Nov 13 '18 at 17:02