Solved

unblocking a call to URLConnection.getInputStream

Posted on 2002-03-14
11
786 Views
Last Modified: 2008-01-16
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
Comment
Question by:rudehost
  • 6
  • 5
11 Comments
 
LVL 16

Expert Comment

by:heyhey_
ID: 6871467
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
 

Author Comment

by:rudehost
ID: 6871627
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
 
LVL 16

Expert Comment

by:heyhey_
ID: 6871673
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
Independent Software Vendors: 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!

 

Author Comment

by:rudehost
ID: 6888954
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
 
LVL 16

Expert Comment

by:heyhey_
ID: 6890711
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
 

Author Comment

by:rudehost
ID: 6894896
<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
 

Author Comment

by:rudehost
ID: 6895274
<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
 
LVL 16

Accepted Solution

by:
heyhey_ earned 230 total points
ID: 6899142
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
 

Author Comment

by:rudehost
ID: 6899435
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
 
LVL 16

Expert Comment

by:heyhey_
ID: 6899446
thanks for the points.

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

Expert Comment

by:heyhey_
ID: 6957509
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

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.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
servlet example 11 55
Java: anonymous class 4 37
Java syntax, or is it Selenium 6 37
Coding for the first time 9 62
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

680 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question