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();
}
}
Normally, a try with resource (see reference) should handle this: