private HttpResponse executeRequest( final Callable<HttpResponse> task, final long timeout, final TimeUnit unit) throws TimeoutException, IOException { ExecutorService executor = Executors.newSingleThreadExecutor(); try { Throwable lastCause = null; long endTime = System.currentTimeMillis() + unit.toMillis(timeout); while (System.currentTimeMillis() < endTime) { Future<HttpResponse> result = executor.submit(task); try { return result.get(timeout, unit); } catch (InterruptedException ex) { throw new IllegalStateException(ex); } catch (ExecutionException ex) { lastCause = ex.getCause(); // HttpURLConnection throws FileNotFoundException on 404 so handle this if (lastCause instanceof FileNotFoundException) { HttpResponse httpResult = new HttpResponse(); httpResult.setStatusCode(HttpURLConnection.HTTP_NOT_FOUND); return httpResult; } else { continue; } } } TimeoutException toex = new TimeoutException(); if (lastCause != null) { toex.initCause(lastCause); } throw toex; } finally { executor.shutdownNow(); } }