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();
}
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.
it’s just what i am finding,thanks!