Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4143518
Votes 225
Synopsis Need ability to set socket options on URLConnection
Category java:classes_net
Reported Against 1.3 , 1.4 , 1.1.6 , 1.2.2 , 1.3.1 , 1.4.1 , 1.4.0_01 , kestrel-rc1 , merlin-beta3
Release Fixed
State 11-Closed, duplicate of 4700777, request for enhancement
Priority: 4-Low
Related Bugs 4532321 , 4619527 , 4700777 , 4730518 , 6201633
Submit Date 28-MAY-1998
Description




Enhancement request.  Need ability to set
socket options on URLConnection class or a way
to get the underlying socket.  Most useful for
long lived http connections which are needed to
get through most firewalls.  Socket Timeout is
the one I need most.
(Review ID: 32523)
======================================================================




java version "1.3.0rc1"


I would like to use URLConnection to allow my applet to communicate
efficiently with my servlet server.  In order to get around firewalls and to use
the browser's SSL encryption mechanisms, I am using standard HTTPS "request"
type communications.  However, for efficiency's sake, I'd like the connection to
remain open with a Keep-Alive connection.  The trouble is that there is no way
that I can see in the JDK to dynamically set the client's KeepAlive timeout
setting.  I'd like to be able to set it for say, 5 minutes.  Unfortunately, the
timeout setting seems to be implementation dependent, and the Java 1.3RC1
plug-in seems to have a very short Keep-Alive setting (< 5 seconds).  If there
were a way in URLConnection or in another class to set the system's Keep-Alive
setting, it would be very helpful.
(Review ID: 102814)
======================================================================





Under "Evaluation" for this feature request, 4143518, the
comment is that the feature could be implemented in some
sort of SocketFactory mechnism like the way JSSE implemented
it.  I want to add that whatever mechanism you all create
to implement this feature, please make sure it can work in an
untrusted applet.  There are many many applications for applets
that are able to have a constant KeepAlive connection back
to the originating web server, but it would be a disservice if
we are forced to have our typically technophobic users enter
into the frightening world of certificates and keystores.

(Review ID: 102814)
======================================================================




java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

When using a URLConnection  customer  against a web server that sends back
'keep-alive' in the HTTP header for the Connection field, the client closes
the underlying socket 5 seconds after the response has been recieved.

All the objects that were used in the initial request/response are still in
scope (i.e. this is not a side effect due to the GC doing its job).

I changed the Connection field value in the response to 'close' and the
connection was closed immediately (as it should be). However, when I use 'keep-
alive', the connection does stay open for a short period, but is closed 5
seconds after the response has been recieved. As a result, I can't reuse that
connection.

// CODE
	public void run() {
		try {
			URL url = new URL("http://localhost");
			URLConnection connection = null;
			BufferedWriter writer = null;
			BufferedReader reader = null;
			String line = null;

			// LOGIN
			connection = url.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			connection.setRequestProperty("Content-
Type", "text/xml");

System.out.println("CLASS: " + (connection.getClass()).getName());

			writer = new BufferedWriter(
				new OutputStreamWriter
(connection.getOutputStream()));
			System.out.println("SENDING:\n" + logindoc);
			writer.write(logindoc, 0, logindoc.length());
			writer.close();

System.out.println("CONNECTION: " + connection.getHeaderField("Connection"));
			reader = new BufferedReader(
				new InputStreamReader(connection.getInputStream
()));
			System.out.println("\nRECIEVED:");
			while((line = reader.readLine()) != null) {
				System.out.println(line);
			}
			reader.close();
// Its during the following sleep that the server side gets a null on the
// socket indicating the client is issuing an EOF.
try { sleep(6000); }
catch(InterruptedException e) {}
			// PUBLISH
			connection = url.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			connection.setRequestProperty("Content-
Type", "text/xml");

			writer = new BufferedWriter(
				new OutputStreamWriter
(connection.getOutputStream()));
			System.out.println("SENDING:\n" + pubdoc);
			writer.write(pubdoc, 0, pubdoc.length());
			writer.close();

			reader = new BufferedReader(
				new InputStreamReader(connection.getInputStream
()));
			System.out.println("\nRECIEVED:");
			while((line = reader.readLine()) != null) {
				System.out.println(line);
			}
			reader.close();
(Review ID: 107635)
======================================================================




java version "1.3.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_01)
Java HotSpot(TM) Client VM (build 1.3.1_01, mixed mode)

There doesn't seem to be any facility for timing out an HttpURLConnection.  You
should be able to specify the number of milliseconds that you are willing to
wait for the connection to be established, before taking an alternate course of
processing (likely through catching an exception).
(Review ID: 135189)
======================================================================
Work Around
N/A
Evaluation
	The URLConnection api normally abstracts away the socket and raw
HTTP connection and instead models single request/reply transactions.
The only way I can forsee allowing application code to access or
manipulate socket level issues is in the context of allowing a
custom socket factory to be set on a protocol-specific subclass of
URLConnection such as HttpURLConnection. In that case, persistent
HTTP connections, pipelining and the like would only be shared across
HttpURLConnection instances that passed in a common socket factory instance.

	This request will be considered in the broader context of
exposing a socket factory construct.

  xxxxx@xxxxx   1998-10-30

One possibility is through the use of SocketFactory, like what JSSE did in its HttpURLHandler.

  xxxxx@xxxxx   2000-02-08
====================================================================

Independent of the outcome of this rfe, the following may be useful.
A system property "http.defaultSocketTimeout" is being defined
for 1.4 which will define a maximum number of milli-seconds to wait
in a blocking read in HTTP connections. A SocketTimeoutException
will be thrown if the timeout is reached.

  xxxxx@xxxxx   2001-02-02
===================================================================



Developers tracking this RFE should check-out 4700777 as tiger (1.5)
has introduced new setReadTimeout and setConnectTimeout methods to
java.net.URLConnection so that applications can specify the read and
connect timeouts.

For 1.4.x the workaround is to use the sun.net.client.defaultReadTimeout
and sun.net.client.defaultConnectTimeout system properties. These
system properties are specific to the Sun provided protocol handlers
and aren't a general/API solution. However they are useful workaround
until tiger is released.
Comments
  
  Include a link with my name & email   

Submitted On 23-JUL-1998
welchrl
I have a need to be able to set the socket options
&quot;Globally&quot;, for example, I don't want any socket to block
my intranet application for more that x seconds.
The third party software interprets my request to their 
gateway and uses either a TCP: (Socket) or HTTP:
(SocketStream) to satisfy my request for data.
Both implementations use the PlainSocketImpl in the factory
to set up the socket.
The problem is that the PlainSocketImpl is not
visible to my code and while it has many options,
none are available to me.  It would seem that some
public static methods on class PlainSocketImpl would let me set 
the available options, hopefully on a global basis.


Submitted On 27-MAR-2000
gmonsen
Please make sure that whatever solution you create does not require an applet to be trusted.  There are many 
applications for general purpose applets in which it would be helpful for them to have a constant connection back to 
the originating server.  It would be a disservice if we were forced to require general technophobic users to enter into 
the frightening world of certificates and signed applets.


Submitted On 14-APR-2000
bestsss
The best I managed to do is telling the server to close the connection. This automaticly will throw 
IOException, however the problem is tooooo long lag. Solution with InputStream.available() is no 
&lt;i&gt;available&lt;/i&gt; just because method blocks, too!


Submitted On 20-JUL-2000
macinta
In my previous post I said I knew of no workaround for https
connections not timing out in the JSSE.  I've figured out a
workaround, but it's not pretty.  I wrote a
WrappedHttpsURLConnection class which extends
com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnection. 
It must be in the
com.sun.net.ssl.internal.www.protocol.https package to do
this, which means that a custom JAR is required for my
bootclasspath.  Anyway, this WrappedHttpsURLConnection
replaces its sslSocketFactory with a WrappedSSLSocketFactory
which wraps up the default SSLSocketFactory in a single
instance per WrappedHttpsURLConnection.  This
WrappedSSLSocketFactory keeps track of all the sockets which
are opened through it and when the
WrappedHttpsURLConnection.disconnect() method is called, all
of the sockets which have been captured are closed.  This
actually works better than my workaround for
HttpURLConnections in practice, but it is less elegant (not
that my HttpURLConnection workaround was elegant by any
stretch of the imagination).


Submitted On 20-JUL-2000
macinta
Osumike is absolutely right - there needs to be a way to
specify a timeout for the URLConnection.  Currently, a
timeout can be achieved by using a separate thread to
monitor the transfer, but THIS ONLY WORKS AFTER THE SERVER
HAS STARTED SENDING THE CONTENT.  If the client has
connected to the server, but the server hasn't sent all the
headers yet this won't work because all of the methods which
would provide access to an object which would close the
connection (e.g., getInputsream()) block.  Try this simple
example to see how much of a problem this is:  write a
simple server that will accept a connection and read any
input on that connection, but never write any output and
never close the connection.  Now try connecting to it with a
URLConnection (e.g., if it's on port 9000 use
http://127.0.0.1:9000).  The URLConnection will hang
indefinitely and there is no way to stop it (that I've
found) without resorting to writing wrappers for the classes
in the sun.net.www.protocol.http (yuck) or creating a custom
SocketFactory.  I think having to resort to building a
custom SocketFactory just to get the connection to time out
properly is poor design because when any code actually needs
to set its own SocketFactory (e.g., the JSSE) it won't be
able to because there will already be this timeout socket
factory in place.  In fact, the problem does affect &quot;https&quot;
URLs when the JSSE is used and I know of no workaround for
it.

What I would consider an ideal solution would be to add a
disconnect() method to the URLConnection.  Also, the
disconnect() methods within the HttpURLConnection and (JSSE)
HttpsURLConnection classes need to be fixed so that they
work regardless of where in the process they are. 
Currently, calling HttpURLConnection.disconnect() internally
causes the client to attempt to reconnect and it does not
release any of the callers which were blocking while the
client waited for input.  If that is the intended
functionality, then a new method (e.g., close()) needs to be
added which severs the connection, does not try to
reconnect, and releases any callers that were blocking
waiting for input.


Submitted On 11-JAN-2001
dkf
A &quot;simple&quot; workaround is to not use the URLConnection class,
and open all the sockets yourself instead.  Not that I claim
this to be in any way optimal or sensible, but it might help
the desperate...


Submitted On 08-FEB-2001
geek
It's crazy that this has not been fixed yet.
It was reported in 1998!

Come on SUN, how can you have a useful URL connection 
without a socket timeout?  I thougt java was supposed to be 
the network language -- a network with no timeouts I 
suppose.


Submitted On 26-FEB-2001
bestsss
&quot;http.defaultSocketTimeout&quot; 
That will be great when comes true!


Submitted On 13-MAR-2001
jserna
http.defaultSocketTimeout will not be enough if different timeouts are required for different connections. It 
will be necessary to also define methods that allow to modify this timeout.


Submitted On 26-APR-2001
i7wegman
There sould be a ways to set the Socket, which is used for
the URLConnection - not a SocketImplFactory! And the must be
a way to call Socket.connect()!


Submitted On 09-MAY-2001
chamness
We can thank Gosling and Payne for this special code design.
The base class for all network connections (ftp, http, etc.)
is listed below.  This class simply wraps a socket.
As a quick and diry workaround, I've added a few lines
which set the timeout on the socket.  You would need
to use this class instead of the default root classes by
prepending the bootstrap class path:
java -Xbootclasspath/p:<CLASSPATH>

Not beautiful, but desparate times require desparate 
measures.

Given the comments from the Evaluation, it seems that rather
than re-architecting with a proper solution, 
Sun is considering something along the lines
of what I've listed here.  (But instead of hard-coding the
timeout, pick it up from the System properties.)

I was hoping that since the original code was hastily 
written by Jonathan Payne in 1994, Sun would take a fresh
stab at the networking code sometime and do a re-design.
("The network is the computer...")   ;-)

/*
 * @(#)NetworkClient.java   1.25 00/02/02
 *
 * Copyright 1994-2000 Sun Microsystems, Inc. All Rights 
Reserved.
 *
 * This software is the proprietary information of Sun 
Microsystems, Inc.
 * Use is subject to license terms.
 *
 */
package sun.net;

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.net.URL;

/**
 * This is the base class for network clients.
 *
 * @version 1.25, 02/02/00
 * @author  Jonathan Payne
 */
public class NetworkClient {
    /** Socket for communicating with server. */
    protected int   timeout = 2000; //timeout in 
milliseconds

    /** Socket for communicating with server. */
    protected Socket    serverSocket = null;

    /** Stream for printing to the server. */
    public PrintStream  serverOutput;

    /** Buffered stream for reading replies from server. */
    public InputStream  serverInput;

    /** Open a connection to the server. */
    public void openServer(String server, int port)
    throws IOException, UnknownHostException {
    if (serverSocket != null)
        closeServer();
    serverSocket = doConnect (server, port);
    serverOutput = new
        PrintStream(new BufferedOutputStream
(serverSocket.getOutputStream()),
                       true);
    serverInput = new BufferedInputStream
(serverSocket.getInputStream());
    }

    /**
     * Return a socket connected to the server, with any
     * appropriate options pre-established
     */
    protected Socket doConnect (String server, int port)
        throws IOException, UnknownHostException
    {
        System.out.println("MY CONNECT");
        //return new Socket (server, port);
        Socket socket = new Socket (server, port);
        socket.setSoTimeout(timeout);
        return socket;
    }

    /** Close an open connection to the server. */
    public void closeServer() throws IOException {
    if (! serverIsOpen()) {
        return;
    }
    serverSocket.close();
    serverSocket = null;
    serverInput = null;
    serverOutput = null;
    }

    /** Return server connection status */
    public boolean serverIsOpen() {
    return serverSocket != null;
    }

    /** Create connection with host <i>host</i> on port 
<i>port</i> */
    public NetworkClient(String host, int port) throws 
IOException {
    openServer(host, port);
    }

    public NetworkClient() {}
}


Submitted On 01-JUN-2001
qwertin
So do we have this http.defaultSocketTimeout or not in 
1.4 ??? it doesn't seem to be documented anywhere ..


Submitted On 12-JUL-2001
pmeigs
You can set a timeout for IE5 with the following registry 
setting: (make a .reg file from this)
<snip snip>
REGEDIT4

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion
\Internet Settings]
"ReceiveTimeout"=dword:0001d4c0
</snip snip>
This will set a 2 minute timeout rather that the 1 hour 
default.  Take a look at wininet.dll documentation esp. the 
InternetSetOption() call.  My guess is that each of these 
options map to a registry setting.  It's not too useful 
because its global to IE but its better than 1 hour.  I was 
having a problem with unrecovered dropped TCP packets that 
was hanging my applet and this give me a timeout better 
than the hour.  I haven't found a corresponding timeout for 
NS yet.



Submitted On 15-OCT-2001
macinta
I finally got around to writing a web page describing why
the HttpURLConnection.disconnect() method is broken and
inadequate for use in timing out an HttpURLConnection.  I
provide test classes which demonstrate the problem on this
page.  I've also provided a hack that is less intrusive than
anything listed here thus far (it doesn't require messing
with your bootclasspath).  At least this will hopefully help
alleviate the timeout problem until we can set the socket
options on a per-URLConnection basis:

http://www.twmacinta.com/myjava/ucon_timeout.php


Submitted On 14-NOV-2001
akurland56
I found a wonderful library at www.innovation.ch which 
implements timeout very nicely.
-Adam


Submitted On 31-JAN-2002
adam@organic.com
IMHO the solution discussed in the evaluation isn't very 
satisfying.  It seems like a bit of a breach of layering.  
Continuing down this path, eventually all of the socket 
options will be mirrored as Sun specific system properties.
I think that it might be nicer to provide a mechanism by 
which an URLConnection can be constructed using a pre-
existing socket.  This would allow advanced users to build 
the socket, set the advanced options on it, and then build 
the URLConnection around it.  Alternately a mechanism could 
be provided to retrieve the socket from the URLConnection, 
but this seems trickier because of sequencing issues (when 
is it legal to set options, etc?)


Submitted On 15-FEB-2002
bestsss
to be clear (see the prev. post). I have voted for that bug.
hoever I guess it should be only Connction and Read (perhaps
write, as well) timeout. Sp sun does fine for now


Submitted On 15-FEB-2002
bestsss
to adam@organic.com
URL means Unified Resource Localtor. It can be on hard disk
or whatever u like. if u can open a socket a resource u
don't need the locator any more, right!
the idea of URLConnection is to provide common mech. of
getting content/InputStream on a resource. So, sockets
shouldn't be messed directly to URLs


Submitted On 22-JUL-2002
jchamlin
Just FYI, we've been experimenting with the JDK 1.4 declared 
way of doing timeouts using 
sun.net.client.defaultConnectTimeout and 
sun.net.client.defaultReadTimeout and it still hangs! I'm 
pretty sure it's hanging after the connection but before any 
reads take place (maybe in getInputStream()). There must be 
a blocking call that doesn't have a timeout that Sun missed. 
Or alternately we are setting these with System.setProperty
(), maybe this is another case of a "read-only" system 
property (i.e. one that Sun reads at startup and caches so 
changes to it won't effect anything) I can't believe Sun has 
had four years to deal with this problem (this was filed in 
1998) and they still didn't fix it right.


Submitted On 03-AUG-2002
scsulliv
Workaround:  
use http://jakarta.apache.org/commons/httpclient/


Submitted On 02-NOV-2002
bakgerman
This problem should not be solved by adding more system 
properties into the JDK.  If I, for example, use a 3rd party 
library which sets the sun.net.client.defaultReadTimeout 
property, that affects my application as well.  Also, Sun 
keeps adding in more system-wide properties for the 
networking APIs because it's a hack solution that allows 
them to keep the method signatures in java.net the same.  
So to get the behavior you want, you're left with both calling 
the right APIs AND also setting the right system properties 
to the right values.  But the system properties are global 
variables, and are not type safe.  In C/C++ this would be like 
having an extern void * variable which if someone (you or a 
3rd party library) set to something other than its default 
value of NULL, suddenly affects the entire socket library.  
Setting a system wide property to affect the behavior of a 
single method on a single object is not OOP, and there are 
far too many global system properties for the java.net APIs 
as it is, especially in the JDK 1.4 release.  These need to be 
settable via a constructor argument or a set/get pair on a 
>>specific<< URL, URLConnection, or Socket object, so that 
the setting is not global.  There are existing free/open C++ 
wrappers around the C socket APIs that accomplish this 
today.  A URL directly implies I/O is going to occurr, and 
since IMO any I/O API needs a timeout setting, thus the URL 
APIs need a timeout setting.  That does NOT mean we should 
expose the underlying socket via getSocket()/setSocket() 
methods on URLConnection, but it does mean that externally 
visible, i.e. public, behavior of an object, in this case the 
URLConnection, needs to be able to be set by the user of the 
object.  All URLs except for a file:// URL incur a socket 
connection.  For that matter, even a file:// URL can incur a 
socket connection if the file is actually on a SAMBA or NFS 
drive and not local.  The java.nio APIs in 1.4 are better, but 
still crippled without this feature.  


Submitted On 03-JUN-2003
chris_mok
Happy 5th Anniversary!


Submitted On 19-JUN-2003
geek
wow chris, you're right.... 5 years and this BUG still has not 
been fixed... 5 YEARS


Submitted On 20-JUN-2003
jcc
Believe it or not, but we're doing something about it.
Tiger, aka 1.5.0, should contain an API to set timeouts on
HttpURLConnections. See bugID 4700777 for details.


Submitted On 09-JUL-2003
MartinHilpert
sun.net.client.defaultConnectTimeout
sun.net.client.defaultReadTimeout

still doesn't work (with JDK 1.4.2) - no exception is ever 
thrown, the HTTPURLConnection hangs forever. :-(


Submitted On 04-DEC-2003
Valeri.Atamaniouk
This is not a vote for the feature, as IMHO the facility itself is 
not usable for server developers.
We have give up to resolve issues with URLConnection 
network management. Finally our product uses own 
implementation for HTTP and HTTPS clients. The tests show 
that custom implementation (using java.nio) works much 
better performance-wise. But that is not really an option for 
Applet developers, I believe.


Submitted On 05-FEB-2004
wjche
setting defaultReadTimeout does not work in
Java Web Start for 1.4.x


Submitted On 24-FEB-2004
J.vanReenen@amc.uva.nl
I tried the sun.net.client.defaultReadTimeout in 1.4.2_03
and it timed out.  But only after twice the time specified.

System.setProperty ("sun.net.client.defaultReadTimeout",
"30000");
This is a time out which should occur after 30 secs. But is
is thrown after 1 minute :(



PLEASE NOTE: JDK6 is formerly known as Project Mustang