views:

76

answers:

4

A Connection is timing out, and the developer on it is at the bottom of his list of ideas.

The logs have a friendly:

[6/24/10 6:32:34:032 EDT] 0000000d ThreadMonitor W   WSVR0605W: Thread "WebContainer : 136" (0000c53e) has been active for 719542 milliseconds and may be hung.  There is/are 45 thread(s) in total in the server that may be hung.

And the code looks like:

    try {
        final URLConnection connection = url.openConnection();
        connection.setConnectTimeout(CONNECT_TIME_SECONDS * 1000);
        connection.setReadTimeout(READ_TIME_SECONDS * 1000);
        is = connection.getInputStream();
        document = builder.parse(is);
    } catch (SAXException e) {
        log.error(e);
        throw new PageContentException(e);
    } finally {
        if (is != null) {
            is.close();
        }
    }

My best guess is that url.openConnection() is attempting to open the connection before the connect timeout was lowered to something reasonable, but nothing in the API shows me how I'd do that differently.

Suggestions on what to try?

A: 

it maybe because of "final". I'm not sure why you are putting in there, but I think removing final should help.

Ankiov Spetsnaz
no way it's because of `final`
unbeli
Final makes it so that connection can't be reassigned later; that shouldn't cause a timeout, I don't think.
Dean J
Why do you think that? Please elaborate...
Thorbjørn Ravn Andersen
More to the point why you *do* think that making it final could affect the timeout? It doesn't make any sense.
EJP
I thought making a socket final would lock up the IOstream. And clearly I was wrong.
Ankiov Spetsnaz
+1  A: 

I'd get the thread dump and see where exactly it's stuck. Don't assume. Then you can see why it's stuck there. If you already have the thread dump, please post the stack trace.

unbeli
There's a logger message before and after this block. The "before" message pops up 50ish times in a row without ever getting the "after". Glad to grab a stack trace next time this hangs, but I have to wait; I restarted the server a few hours back, so the previous stack traces are gone.
Dean J
A++ on your answer. I made a mistake on this one. The log messages match *another* section of the code as well - the original dev did a bit of cut and paste there. Instead of calling connection.getInputStream() - which abides by the timeouts - we were calling url.openStream() in that second block of code, which does not abide by a timeout. The kill -3 <pid> heap dump gave us the *correct* place in the code, and this became pretty darn easy after that.
Dean J
+1  A: 

My best guess is that url.openConnection() is attempting to open the connection before the connect timeout was lowered to something reasonable, but nothing in the API shows me how I'd do that differently.

I think this is the likely scenario. Setting the connection timeout after attempt to connect has started is unlikely to work, IMO.

Suggestions on what to try?

Have you tried setting the "sun.net.client.defaultConnectTimeout" property in the system properties? It is documented here.

Stephen C
Okay, that might be the winner. In any case, +1.
Dean J
I don't think this is the case. The connection is not supposed to start until the streams are asked for or explicit connect() is done.
unbeli
@unbeli - that property is supposedly used to give the connect timeout when a socket is opened without a specific timeout parameter. AFAIK, that is what is happening here.
Stephen C
@unbeli: openConnection() doesn't implicitly call connect() in the background, though?
Dean J
@Dean J, no, at least not in my implementation (Sun JDK 1.6.0_16).
unbeli
A: 

My best guess is that url.openConnection() is attempting to open the connection before the connect timeout was lowered to something reasonable.

No. If that was the case URLConnection.setConnectionTimeout() would be completely pointless, as there is no way to call it earlier than you are.

EJP
If you're creating a connection then opening it - not using the URL, as this is - it might be useful. I think the problem is that URL returns an open connection, and only an open connection.
Dean J
No. It returns a connection. You then call the set timeout methods on it. You then do some I/O. Only at that point is an actual TCP/IP connection formed.
EJP