Solved

BufferedReader.readLine() sometimes hangs my app

Posted on 2003-11-04
19
823 Views
Last Modified: 2012-05-04
Hi all,

I have a java application that reads in the contents of a URL every 10 minutes. Basically:

...
BufferedReader in = new BufferedReader( new InputStreamReader(conn.getInputStream()));
String s=null;
System.out.println("about to use readLine()");
while ( (s=in.readLine()) != null) {
//do something
...

Everything works fine, until (at random intervals of several hours), my app just hangs at while ( (s=in.readLine()) != null)

When it 'hangs' it doesn't use any cpu time ... it just sits there for hours. I have to stop (ctrl c) and restart the program in order to get it working again.

Is there some condition that should be met before i attempt in.readLine()? Anything else that could cause this?

Thanks kindly
Ryan
0
Comment
Question by:Spoogi
  • 7
  • 6
  • 5
  • +1
19 Comments
 
LVL 1

Expert Comment

by:JNic
ID: 9681299
Can you post the code where conn is being defined?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 9681373
>>Anything else that could cause this?

Could be just network difficulties. Just trap and log any exceptions.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 9681480
You could cast the URLConnection to HttpURLConnection and only proceed with getting a stream if HTTP_OK:

http://java.sun.com/j2se/1.4.2/docs/api/java/net/HttpURLConnection.html#HTTP_OK
0
Industry Leaders: 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:Spoogi
ID: 9681498
Jnic:
                      URL url = new URL(newsfeedURL);
                      URLConnection conn = url.openConnection();
                      conn.setDoOutput(true);
                      PrintWriter pw = new PrintWriter( conn.getOutputStream());
                      pw.print("client_id=xxxxxxx");

CEHJ:

I am trapping all exceptions, and none is thrown in this case.  If the remote site is down, the exception (SocketException) is thrown & logged.

Thanks
0
 

Author Comment

by:Spoogi
ID: 9681851
CEHJ:

I'll try your suggestion.  I've inserted the following into my code prior to "while ( (s=in.readLine()) != null)":

                        HttpURLConnection httpConnection = (HttpURLConnection)conn;
                        int code = httpConnection.getResponseCode();
                        if (code != HttpURLConnection.HTTP_OK)
                        {
                           String message = httpConnection.getResponseMessage();
                           System.out.println(code + " " + message);
                           return;
                        } else {
                               System.out.println("HTTP_OK: "+code);
                        }

It's nothing but informative at this point, but will let me know what the response code is the next time the 'hang' happens.  Stay tuned, will probably take several hours for it to re-occur.

Thanks
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 9681868
OK - not sure if you need to print the OK code ;-)
0
 
LVL 92

Expert Comment

by:objects
ID: 9681890
Try reading the content with a stream instead of a reader and see if the problem still occurs. If it doesn't then simply convert the bytes read into a stream after they are read instead of having the reading handle the conversion.
0
 

Author Comment

by:Spoogi
ID: 9695452
More on this.  The HttpURLConnection is always OK.  It starts reading in lines of the bufferedreader, and then will sometimes just hang in the process.  No unusual characters in the document or anything, and never on the same document twice ... appears to be random to me.

objects:  I'm not entirely certain what you are suggesting ... I'll have to do a little research on how to read the content with a stream.

Thanks
0
 
LVL 92

Expert Comment

by:objects
ID: 9697326
>  I'm not entirely certain what you are suggesting

I meant instead of using a Reader, read the bytes directly from the stream.

InputStream in = request.getInputStream();
while (-1!=(in.read())
{
   // if this works then we can construct a String from the data read
}
0
 

Author Comment

by:Spoogi
ID: 9698252
Thanks for the code example objects.

May I ask why you suggest using a Reader may be causing the problem?  Would the following satisfy your hunch?

                            InputStream inStream=conn.getInputStream();
                            BufferedReader in = new BufferedReader( new InputStreamReader(inStream));

                            System.out.println("Starting to read in stream");
                            while ((inStream.read()!=-1) && ( (s=in.readLine()) != null)) {
                                System.out.println(s);
                            }

i.e: I've added the "(inStream.read()!=-1)".  
Prior to adding this, in the case of a lockup, I would most often see "Starting to read in stream" print to the terminal, and System.out.println(s) would not show.  So it must have something do to with (s=in.readLine()) ???  

I'm in kind of a touchy environment:
- the lockup takes several hours, if not days to occur
- the remote server only allows my client_id to access it at 10 minute intervals
- the xml newsfeeds I am pulling down drive other internal applications that are in production

cry me a river, I know, but because of that last point I'm hesitant to re-write my app.  If you think this latest change could make the difference then I'll let things run till the next lockup.  If you're not convinced my change will make the difference, then perhaps I'll re-write over the weekend to follow your suggestions more closely.  Any other ideas would be helpful.

Thanks again

PS- I've heard a suggestion of using another thread to monitor this one and interject if it 'hangs' for a while.  I'm not sure if that's a good idea, or even how to do it.
0
 
LVL 92

Expert Comment

by:objects
ID: 9698289
> May I ask why you suggest using a Reader may be causing the problem?

Am just trying to simplify the process to better determine the cause.

> Would the following satisfy your hunch?

Not really, cause a Reader is still involved.


You could try and use a different http implementation instead of URLConnection.
Such as HTTPClient.
0
 
LVL 92

Expert Comment

by:objects
ID: 9698328
Does the server specify the http content length?

Using the stream approach I suggested above would allow you to determine at how many bytes had been read when it hangs which may give some clues.
0
 
LVL 92

Accepted Solution

by:
objects earned 250 total points
ID: 9698365
0
 

Author Comment

by:Spoogi
ID: 9698638
HTTPClient looks promising:

       setTimeout(int time)
                 Sets the timeout to be used for creating connections and reading responses.

I'm working on implementing right now.
Thanks
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 9699831
You can set timeouts as follows (or if you prefer, using System.setProperty in your code):

java -Dsun.net.client.defaultConnectTimeout=30000 -Dsun.net.client.defaultReadTimeout=30000

if these are exceeded, an exception will be thrown, allowing you to wait until later to try again
0
 

Author Comment

by:Spoogi
ID: 9704538
Objects:  I accepted your answer. HTTPClient does a fantastic job.  Thank you

CEHJ: Thank you as well.  I would have preferred to use your 'pure sun' solution.  But alas, now that the duct tape is holding I must move on to other things.  I'm definitely going to remember your timeout solution the next time....
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 9706627
...always a good idea to restrict yourself to the standard libraries if possible. And a points split might have been nice ..;-)
0
 

Author Comment

by:Spoogi
ID: 9707005
:-O  Sorry - didn't realize I had the option!
0
 
LVL 92

Expert Comment

by:objects
ID: 9718499
0

Featured Post

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!

Question has a verified solution.

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

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 Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.

756 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