FULL PRODUCT VERSION :
I saw the following Exception stack trace:java version "1.5.0_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05)
Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
I have a program which runs nightly and web scrapes pages of financial data from Yahoo.
I frequently observe the following Exception stack trace:
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
The bug is that no time out should EVER happen, since both of the time out parameters (connect as well as read) of the URLConnection were 0 (i.e. infinite time out)--see below for more details.
The bug is almost certainly related to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6209838
I say this because I abandoned using URLConnection objects and went directly to using raw sockets to mine Yahoo's webpages and I was still seeing tons of ConnectExceptions, most especially when many threads of mine were trying to concurrently hit Yahoo. I somewhat mitigated the problem by greatly reducing the number of mining threads. But it still exists and is very annoying. Please treat this bug as important!
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The relevant code is the following snippet:
/**
* This method creates a URLConnection for url, opens an InputStream from it, and returns the InputStream.
* <p>
* @throws IllegalArgumentException if url == null
* @throws IOException if an I/O problem occurs
* @throws UnknownServiceException if the protocol does not support input
*/
public static InputStream getInputStream(URL url) throws IllegalArgumentException, IOException, UnknownServiceException {
if (url == null) throw new IllegalArgumentException("arg url is null");
URLConnection conn = url.openConnection();
conn.connect();
return conn.getInputStream();
}
This code creates a URLConnection, connects it, and then returns its InputStream (which subsequently gets all of its bytes read out of it by some other code; these are the bytes that make up the Yahoo web page).
This code fragment is where the above mentioned.java.net.ConnectException is being thrown.
In order to prove what time out parameters are in effect, I have modified that method as follows to catch any IOException such as the ConnectException:
/**
* This method creates a URLConnection for url, opens an InputStream from it, and returns the InputStream.
* <p>
* @throws IllegalArgumentException if url == null
* @throws IOException if an I/O problem occurs
* @throws UnknownServiceException if the protocol does not support input
*/
public static InputStream getInputStream(URL url) throws IllegalArgumentException, IOException, UnknownServiceException {
if (url == null) throw new IllegalArgumentException("arg url is null");
URLConnection conn = null;
try {
conn = url.openConnection();
//conn.setConnectTimeout( Integer.MAX_VALUE );
//conn.setReadTimeout( Integer.MAX_VALUE );
conn.connect();
return conn.getInputStream();
}
catch (IOException ie) {
throw new RuntimeException("see cause for details, but conn.getConnectTimeout() = " + conn.getConnectTimeout() + " and conn.getReadTimeout() = " + conn.getReadTimeout(), ie);
}
}
Doing this, the stack trace of the RuntimeException which wraps the ConnectException looks like:
java.lang.RuntimeException: see cause for details, but conn.getConnectTimeout() = 0 and conn.getReadTimeout() = 0
at bb.net.UrlUtil.getInputStream(UrlUtil.java:105)
at bb.net.UrlUtil.drainIntoString(UrlUtil.java:84)
at bb.finance.misc.Yahoo.mineSecurity(Yahoo.java:620)
at bb.finance.misc.Yahoo$MineSecurityTask.run(Yahoo.java:572)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
As can be seen from the message line, both the connect and read time outs are 0 which according to their javadocs indicates infinite timeouts (i.e. should never occur):
0 return implies that the option is disabled (i.e., timeout of infinity).
http://java.sun.com/j2se/1.5.0/docs/api/java/net/URLConnection.html#getConnectTimeout()
Returns setting for read timeout. 0 return implies that the option is disabled (i.e., timeout of infinity).
http://java.sun.com/j2se/1.5.0/docs/api/java/net/URLConnection.html#getReadTimeout()
I have also experimented with setting both time outs to Integer.MAX_VALUE by uncommenting the 2 commented out lines above, but that likewise still frequently results in timeouts being seen.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Time out should never occur for a time out parameter of 0.
ACTUAL -
Time outs do occur.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.Socket.connect(Socket.java:507)
at java.net.Socket.connect(Socket.java:457)
at sun.net.NetworkClient.doConnect(NetworkClient.java:157)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:365)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:477)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:214)
at sun.net.www.http.HttpClient.New(HttpClient.java:287)
at sun.net.www.http.HttpClient.New(HttpClient.java:299)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:792)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:744)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:669)
at bb.net.UrlUtil.getInputStream(UrlUtil.java:101)
... 6 more
REPRODUCIBILITY :
This bug can be reproduced often.
CUSTOMER SUBMITTED WORKAROUND :
None that I know of, and if you do please let me know ASAP as this problem is hurting me big time.
Note that someone else maybe saw this too:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6242468
(am not sure from this report if it is the same cause as mine or not).
My raw socket code, or at least the most relevant method -
/**
* This method opens a socket to the host and port specified by url,
* creates an input stream (wrapped in a PrintWriter) from it,
* and sends the http headers appropriate for requesting the file specified
by url.
* In addition, the http header specifies that the response type must be one
of the standard text types,
* and that the connection will be closed when this method is done (i.e. no
keep alive).
* It then opens an output stream from the socket and drains all the bytes
into a String which is returned.
* <p>
This method was introduced because of all the time out problems that was
having with Sun's URLConnection.
It was inspired by:
http://www.onjava.com/pub/a/onjava/2003/04/23/java_webserver.html
and
http://computing.dcu.ie/~humphrys/Notes/Networks/java.html
(see section on "The "URL" class hides the sockets")
See also
http://jan.netcomp.monash.edu.au/distjava/socket/lecture.html
If Sun ever listens to my bug report and fixes URLConnection, then this
method becomes obsolete.
* <p>
* @throws IllegalArgumentException if url == null
* @throws IOException if an I/O problem occurs
*/
public static String drainHttpIntoString(URL url) throws
IllegalArgumentException, IOException {
if (url == null) throw new IllegalArgumentException("arg url is null");
Socket socket = null;
try {
int port = (url.getPort() != -1) ? url.getPort() : url.getDefaultPort();
// socket = new Socket(url.getHost(), port );
// The above line often fails on my machine with a connect timeout,
especially when many thread are trying to create sockets.
// This appears to be due to:
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6209838
// But see also:
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6224843
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5092063
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4954495
// So, until the above gets fixed, try:
socket = new Socket(Proxy.NO_PROXY);
//socket.setPerformancePreferences(1, 0, -1); // means prefer connectionTime
over latency over bandwidth
InetSocketAddress socketAddress = new InetSocketAddress(url.getHost(), port
);
socket.connect(socketAddress, Integer.MAX_VALUE);
// no dice: the above still suffers from ConnectExceptions, so the only
(partial) solution is to reduce the number of threads...
PrintWriter pw = new PrintWriter( socket.getOutputStream(), false );
pw.print("GET " + url.getFile() + " HTTP/1.0" + "\r\n");
pw.print("Accept: text/plain, text/html, text/*" + "\r\n");
pw.print("Connection: Close" + "\r\n"); // am not doing any keep alive
pw.print("\r\n");
pw.flush();
return StreamUtil.drainIntoString( socket.getInputStream() );
}
finally {
NetUtil.closeSocket(socket);
}
}
I saw the following Exception stack trace:java version "1.5.0_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05)
Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
I have a program which runs nightly and web scrapes pages of financial data from Yahoo.
I frequently observe the following Exception stack trace:
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
The bug is that no time out should EVER happen, since both of the time out parameters (connect as well as read) of the URLConnection were 0 (i.e. infinite time out)--see below for more details.
The bug is almost certainly related to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6209838
I say this because I abandoned using URLConnection objects and went directly to using raw sockets to mine Yahoo's webpages and I was still seeing tons of ConnectExceptions, most especially when many threads of mine were trying to concurrently hit Yahoo. I somewhat mitigated the problem by greatly reducing the number of mining threads. But it still exists and is very annoying. Please treat this bug as important!
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The relevant code is the following snippet:
/**
* This method creates a URLConnection for url, opens an InputStream from it, and returns the InputStream.
* <p>
* @throws IllegalArgumentException if url == null
* @throws IOException if an I/O problem occurs
* @throws UnknownServiceException if the protocol does not support input
*/
public static InputStream getInputStream(URL url) throws IllegalArgumentException, IOException, UnknownServiceException {
if (url == null) throw new IllegalArgumentException("arg url is null");
URLConnection conn = url.openConnection();
conn.connect();
return conn.getInputStream();
}
This code creates a URLConnection, connects it, and then returns its InputStream (which subsequently gets all of its bytes read out of it by some other code; these are the bytes that make up the Yahoo web page).
This code fragment is where the above mentioned.java.net.ConnectException is being thrown.
In order to prove what time out parameters are in effect, I have modified that method as follows to catch any IOException such as the ConnectException:
/**
* This method creates a URLConnection for url, opens an InputStream from it, and returns the InputStream.
* <p>
* @throws IllegalArgumentException if url == null
* @throws IOException if an I/O problem occurs
* @throws UnknownServiceException if the protocol does not support input
*/
public static InputStream getInputStream(URL url) throws IllegalArgumentException, IOException, UnknownServiceException {
if (url == null) throw new IllegalArgumentException("arg url is null");
URLConnection conn = null;
try {
conn = url.openConnection();
//conn.setConnectTimeout( Integer.MAX_VALUE );
//conn.setReadTimeout( Integer.MAX_VALUE );
conn.connect();
return conn.getInputStream();
}
catch (IOException ie) {
throw new RuntimeException("see cause for details, but conn.getConnectTimeout() = " + conn.getConnectTimeout() + " and conn.getReadTimeout() = " + conn.getReadTimeout(), ie);
}
}
Doing this, the stack trace of the RuntimeException which wraps the ConnectException looks like:
java.lang.RuntimeException: see cause for details, but conn.getConnectTimeout() = 0 and conn.getReadTimeout() = 0
at bb.net.UrlUtil.getInputStream(UrlUtil.java:105)
at bb.net.UrlUtil.drainIntoString(UrlUtil.java:84)
at bb.finance.misc.Yahoo.mineSecurity(Yahoo.java:620)
at bb.finance.misc.Yahoo$MineSecurityTask.run(Yahoo.java:572)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
As can be seen from the message line, both the connect and read time outs are 0 which according to their javadocs indicates infinite timeouts (i.e. should never occur):
0 return implies that the option is disabled (i.e., timeout of infinity).
http://java.sun.com/j2se/1.5.0/docs/api/java/net/URLConnection.html#getConnectTimeout()
Returns setting for read timeout. 0 return implies that the option is disabled (i.e., timeout of infinity).
http://java.sun.com/j2se/1.5.0/docs/api/java/net/URLConnection.html#getReadTimeout()
I have also experimented with setting both time outs to Integer.MAX_VALUE by uncommenting the 2 commented out lines above, but that likewise still frequently results in timeouts being seen.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Time out should never occur for a time out parameter of 0.
ACTUAL -
Time outs do occur.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.Socket.connect(Socket.java:507)
at java.net.Socket.connect(Socket.java:457)
at sun.net.NetworkClient.doConnect(NetworkClient.java:157)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:365)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:477)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:214)
at sun.net.www.http.HttpClient.New(HttpClient.java:287)
at sun.net.www.http.HttpClient.New(HttpClient.java:299)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:792)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:744)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:669)
at bb.net.UrlUtil.getInputStream(UrlUtil.java:101)
... 6 more
REPRODUCIBILITY :
This bug can be reproduced often.
CUSTOMER SUBMITTED WORKAROUND :
None that I know of, and if you do please let me know ASAP as this problem is hurting me big time.
Note that someone else maybe saw this too:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6242468
(am not sure from this report if it is the same cause as mine or not).
My raw socket code, or at least the most relevant method -
/**
* This method opens a socket to the host and port specified by url,
* creates an input stream (wrapped in a PrintWriter) from it,
* and sends the http headers appropriate for requesting the file specified
by url.
* In addition, the http header specifies that the response type must be one
of the standard text types,
* and that the connection will be closed when this method is done (i.e. no
keep alive).
* It then opens an output stream from the socket and drains all the bytes
into a String which is returned.
* <p>
This method was introduced because of all the time out problems that was
having with Sun's URLConnection.
It was inspired by:
http://www.onjava.com/pub/a/onjava/2003/04/23/java_webserver.html
and
http://computing.dcu.ie/~humphrys/Notes/Networks/java.html
(see section on "The "URL" class hides the sockets")
See also
http://jan.netcomp.monash.edu.au/distjava/socket/lecture.html
If Sun ever listens to my bug report and fixes URLConnection, then this
method becomes obsolete.
* <p>
* @throws IllegalArgumentException if url == null
* @throws IOException if an I/O problem occurs
*/
public static String drainHttpIntoString(URL url) throws
IllegalArgumentException, IOException {
if (url == null) throw new IllegalArgumentException("arg url is null");
Socket socket = null;
try {
int port = (url.getPort() != -1) ? url.getPort() : url.getDefaultPort();
// socket = new Socket(url.getHost(), port );
// The above line often fails on my machine with a connect timeout,
especially when many thread are trying to create sockets.
// This appears to be due to:
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6209838
// But see also:
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6224843
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5092063
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4954495
// So, until the above gets fixed, try:
socket = new Socket(Proxy.NO_PROXY);
//socket.setPerformancePreferences(1, 0, -1); // means prefer connectionTime
over latency over bandwidth
InetSocketAddress socketAddress = new InetSocketAddress(url.getHost(), port
);
socket.connect(socketAddress, Integer.MAX_VALUE);
// no dice: the above still suffers from ConnectExceptions, so the only
(partial) solution is to reduce the number of threads...
PrintWriter pw = new PrintWriter( socket.getOutputStream(), false );
pw.print("GET " + url.getFile() + " HTTP/1.0" + "\r\n");
pw.print("Accept: text/plain, text/html, text/*" + "\r\n");
pw.print("Connection: Close" + "\r\n"); // am not doing any keep alive
pw.print("\r\n");
pw.flush();
return StreamUtil.drainIntoString( socket.getInputStream() );
}
finally {
NetUtil.closeSocket(socket);
}
}
- relates to
-
JDK-6209838 WXP SP 2: Several threads cannot attempt socket connection at the same time
-
- Closed
-