Solved

unblocking a call to URLConnection.getInputStream

Posted on 2002-03-14
11
783 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
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 

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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

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

Suggested Solutions

Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…

770 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