We were encountering a problem in the server code at my company whereby
read() requests on a stream were blocking and never returning. This was causing periodic data retrieval within threads to hang, which would eventually eat up all available threads and lead to stale data. I tried creating a watchdog thread which would periodically loop through the data retrieval threads, determine their execution time and then call
Thread.interrupt() if that value exceeded a certain limit. That didn’t seem to work as
interrupt() sets a flag (which can be retrieved through the
interrupted() method) if the target thread is not executing one of
join(). This did not help. As another solution, Colin found a reference in Sun’s Java Developer Connection to a system property called
http.defaultSocketTimeout which would set the timeouts on HTTP connections. This did not work either, for the simple reason that they renamed the property to
net.client.defaultSocketTimeout and then to
sun.net.client.defaultConnectTimeout in J2SDK 1.4.1. Using the former of those last two properties successfully set the read timeout (that being the maximum time allowed between reading one byte and then reading the next) for all connections. Of course, we would not have found this out if Colin hadn’t seen this bug (NOTE: viewing JDC bugs requires a login), which contains a link at the very bottom to the Java networking properties.
The above information is useless if you are stuck with a JVM which doesn’t support 1.4. You will have to somehow
close() the underlying connection, probably from a thread which directly monitors that connection. You could also write your own streams.
Naturally, setting a property which affects all connections in your application is a bad idea, but Java doesn’t provide you with any other way unless you have access to the underlying socket, at which point you could use
Socket.setSoTimeout(). There is a bug requesting the addition of non-global timeout properties for HTTP connections, but this won’t be fixed until Tiger AKA Java 1.5.
People, Java has only been around for some seven years and we’re only just getting per-connection read timeouts? Why wasn’t this done sooner? Is nobody actually using Java as it was meant to be used? Isn’t Java supposed to be a network programming language? It’s not like people don’t want this feature. I mean, look at this bug which requests the ability to set socket options on a
URLConnection. That bug has been around since early 1998, has had 217 votes placed on it and is still labelled as “In progress, request for enhancement”!
Java, baby, I loves you but why you gone make me hurt you so?