URL.openStream() Might Leave You Hanging

The java.net.URL class provides the openStream() method to open an InputStream:

URL myUrl = new URL("http://myhost:port/path/to/something/");
InputStream in = myUrl.openStream();
...
// now use the InputStream to read data

The openStream() method is actually just a shortcut for openConnection().getInputStream(). Here is the code from the URL class:

public final InputStream openStream() throws java.io.IOException {
  return openConnection().getInputStream();
}
Frustrated Computer User

The Problem

You can probably guess that I encountered this issue recently. My client GUI used URL.openStream() to download XML from a REST service. This REST service is just a simple servlet that eventually connects to an Oracle instance.

When the client invoked openStream(), however, the request blocked forever. The client was deadlocked, forcing users to kill the process via task manager. Ouch.

It turns out that Oracle was in a bad state, so the server-side database connection was locked up. One layer up, in the Servlet, the request was blocked. As we continue up the food chain to the client GUI, we find the client blocked on the HTTP request to the servlet.

The Fix

I fixed the problem by adjusting the timeout settings in the client code. The new code looks something like this:

URLConnection conn = url.openConnection();
// setting these timeouts ensures the client does not deadlock indefinitely
// when the server has problems.
conn.setConnectTimeout(timeoutMs);
conn.setReadTimeout(timeoutMs);
in = conn.getInputStream();
...etc

Now, when the same situation occurs (hopefully rarely), the client times out and throws an exception rather than blocking forever. The user sees an error message, but that is a whole lot better than deadlock.

Other Observations

  • The default timeout is 0, which means calls like openStream() block indefinitely. There are cases when you might want this.
  • The fact that my client GUI locked up is a symptom of another bug. Never call methods like this from the event dispatch thread. Alas, we don’t have time to fix everything.
  • I also need to put some timeout logic into the server-side JDBC code.

geln yang Says:

it’s just what i am finding,thanks!

Phil Says:

Genious. Thank you. You have fixed a production issue that was being blamed on my threading.

fei Says:

Thank you ! It’s just the problem that keeps torturing me for many days.And the timeout settings solve the problem perfectly !

scoutice Says:

thank you! i had the same problem and did not even notice, what was the reason. now i fixed it and it works perfectly.

schneimi Says:

I used openStream() in a timer and wondered why the timer stopped working once in a while, so thx for that great explanation, it really helped me.