Solved

unblocking a call to URLConnection.getInputStream

Posted on 2002-03-14
11
778 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_
Comment Utility
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
Comment Utility
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_
Comment Utility
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
 

Author Comment

by:rudehost
Comment Utility
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_
Comment Utility
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
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:rudehost
Comment Utility
<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
Comment Utility
<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
Comment Utility
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
Comment Utility
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_
Comment Utility
thanks for the points.

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

Expert Comment

by:heyhey_
Comment Utility
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
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…
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
This video teaches viewers about errors in exception handling.

728 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now