• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 806
  • Last Modified:

unblocking a call to URLConnection.getInputStream

I have an interesting problem with an applet in Internet Explorer on win98 machines using a dialup.

Specifically the application in question retrieves a urlconnection from a url object and calls getInputStream to read a serialized object from the server.

The problem comes into play when the dialup user disconnects their modem. At that point the call to URLConnection.getInputStream() blocks and never returns.

The creation of the urlconnection does not fail or throw an exception after the dialup is disconnected and a call to urlconnection.connect doesnt either.

When running a similar test on a network where I pull the plug I get an exception with the following stack trace which makes sense.

at com/ms/net/wininet/http/HttpInputStream.connect
at com/ms/net/wininet/http/HttpInputStream.<init>
at com/ms/net/wininet/http/HttpURLConnection.createInputStream
at com/ms/net/wininet/WininetURLConnection.getInputStream

The hanging behavior also appears to be inconsistent and doesnt occur every time the dialup is disconnected and reconnected.

The question is can I construct my attempts to get an input stream to force an exception in the case that the client machine has disconnected his internet session or alternatively is there a reasonable way to have another thread force the getInputStream call to unblock, or alternatively does anyone have a good suggestion on how to get at the connected property of the URLConnection so I could avoid trying to get the inputstream at all in this scenario?

Thanks for any suggestions

0
rudehost
Asked:
rudehost
  • 6
  • 5
1 Solution
 
heyhey_Commented:
for quick test - start another thread and call

inputStream.close();
loaderThread.interrupt();

after 10 seconds. if both of them does not work - try calling

loaderThread.stop();

(this should throw ThreadDeath exception which you can catch yourself).




0
 
rudehostAuthor Commented:
The problem though is that I never get an inputstream to call close on. Its the process of trying to get a reference to an input stream that is hanging.

I have been hesitant to start another thread strictly for the purpose of killing this one but Ill give your suggestion a shot sans the call to inputstream.close()
0
 
heyhey_Commented:
umm right, my mistake :( - the thread is blocked before you even get the InputStream.

last time, when I had such problem, I used the following  solution:
1. isolate the connecting code in a seperate object;
2. 'detach' this object from the main code when stopping the connection.

I do not stop the connector Thread - it will continue its execution when some TCP timeout occures, but it won't have any effect on the main logic.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
rudehostAuthor Commented:
I actually have tried variations of both.

The problem with the stop call is it seems to actually kill the thread at random times sometimes 10 or 12 minutes later. I can tell because I can see console messages I am printing out as the run method exits well after stop was called.

If I detach the object from the application by nulling it there seems to be an issue with the old object holding some tcp resources (same as with stop). What actually happens is that if I detach two of these objects all connections on subsequent objects fail. In some cases I can even see objects that are supposedly dead waking up their input streams to read data that should belong to the current thread.

This is a hairy one so I upped the points and will continue to do so for anyone who can find an effective solution.

0
 
heyhey_Commented:
There is no magic solution.

> The problem with the stop call is it seems to actually kill the thread at random times sometimes 10 or 12 minutes later.

Thread is blocked somewehere deeply inside the native code (most probably .connect() TCP implementation) and you cannot effectively stop it before Java interpreter gets the control.

>  What actually happens is that if I detach two of these
objects all connections on subsequent objects fail.

Some browsers restrict number of simultaneous URLConnections (I have seen restriction for maximum 4 URLConnections in some IE versions). No solution again.

> ... I can even see objects that are supposedly dead waking up their input streams to read data ...

This one depends solely on you code. When you receive control after .connect() you should check if this conection object is marked as "dead" and immediately free all the resources.


This is not just URLConnection problem - I've seen similar behaviour when Socket.connect() call blocks for 5-7 minutes (because of a very restictive firewall)
0
 
rudehostAuthor Commented:
<I>This one depends solely on you code. When you receive control after .connect() you should check if this
conection object is marked as "dead" and immediately free all the resources.</I>

That might actually be the effective solution here but precisely how do I go about that? The connected property is protected and isnt exposed as part of urlconnection or am I missing something?
0
 
rudehostAuthor Commented:
<I>This one depends solely on you code. When you receive control after .connect() you should check if this
conection object is marked as "dead" and immediately free all the resources.</I>

That might actually be the effective solution here but precisely how do I go about that? The connected property is protected and isnt exposed as part of urlconnection or am I missing something?
0
 
heyhey_Commented:
maybe I was not clear enough

my own solution (the only possible one) is to start some watcher thread that will interrupt the connector object and clear all references to it. Connector object MUST release all resources when it detects that it have been destroyed.

follows some code for direct Socket connection.


  public Socket connect() throws LowLevelCommException
  {
    try
    {
      // first do the real work
      // anybody can destroy us while this code is executing
     
      // this code make take ages ....
      // - more than 2-3 minutes
      socket = new Socket(hostName, hostPort);
     
      synchronized (this)
      {
        if (isDestroyed)
        {
        // releaze resources
          try {socket.close();} catch (Exception x){}
          return null;
        }
        else
        {
          return socket;
        }
      }
    } catch (IOException x)
    {
      throw new LowLevelCommException(LowLevelCommException.ERROR_CONNECTERROR, "Could not connect to " + hostName + ":" + hostPort, x);
    } catch (Throwable x)
    {
      logg.log("x", x);
      throw new LowLevelCommException(LowLevelCommException.ERROR_CONNECTERROR, "Unexpected error", x);
    }
    finally
    {
      socket = null;
    }
  }
  public void interrupt()
  {
    synchronized (this)
    {
      isDestroyed = true;
    }
  }
0
 
rudehostAuthor Commented:
Sometimes if you get wrapped up in something its hard to see the forest from the trees which I think was the case here.

My experience with IE browsers is you are really limited to 2 conenctions for the jvm and I was hitting those two.

Checking to see if the thread Im running is the properly active thread and shutting down that stream if it isnt seems to be the magic bullet (or silver at least). Thanks for the help.

0
 
heyhey_Commented:
thanks for the points.

P.S. I have posted another comment which has suddenly disappeared  ??
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now