Tuesday, July 29, 2008

URL.openConnection() can tie up resources

At least on Windows, GWTShellServlet has always had the rather nasty side effect of locking up public resources it serves.  This translates into a user experience of sometimes having to kill hosted mode in order to save over a public resource, which is particularly annoying given that it's much faster to refresh hosted mode than to restart it.

After digging into this a while, I finally found the culprit, and it's URL.openConnection() .  When using this method on a local file, you get back a Sun private FileURLConnection implementation subclass of URLConnection .  Using the Java debugger, I was able to see that on return, a FileURLConnection contains an active FileInputStream ; the purpose of the internal stream is to be the return value of the URLConnection.getInputStream() .  I suppose it's probably more efficient somehow for them to go ahead and create the stream up front, but if you don't end up using its internal stream, the stream doesn't get closed until the object is garbage collected, which potentially might not happen for a long time.  And on Windows, at least, this locks up the target file.

In our case, we had wastefuly been doing a separate URL.openStream() to get a readable stream on the URL, so our fix was to simply use the stream already available in the URLConnection and then close it when done.