"IOException: Bad file descriptor" thrown during readline()

I'm working on a system to send data to bluetooth devices. Currently I have a dummy program that "finds" bluetooth devices by listening for input on System.in, and when one is found, the system sends some data to the device over bluetooth. Here is the code for listening for input on System.in

InputStreamReader isr =new InputStreamReader(System.in);

BufferedReader br =new BufferedReader(isr);

boolean streamOpen =true;

while(streamOpen){

String next ="";

System.out.println("waiting for Input: ");

try{

next = br.readLine();

// other code here

}catch (IOException ioe){

ioe.printStackTrace();

}

}// end of while

This is running in it's own thread, constantly listening for input from System.in. There is also another thread that handles pushing the data to the bluetooth device. It works the first time it reads input, then the other thread starts running also, printing output to System.out. When the data has successfully been pushed to the device, the system waits for me to enter more information. As soon as I type something and press return, i get an endless (probably infinte if I don't kill the process) list of IOExceptions:Bad file descriptor exceptions that are thrown from the readline() method.

Here is what is being printed:

Waiting for Input:// <-- This is the thread listening for input on System.in

system started with 1 Bluetooth Chip // From here down is the thread that pushing data to the BT device

next device used 0

default device 0000000000

start SDP for 0000AA112233

*** obex_push: 00:00:AA:11:22:33@9, path/to/file.txt, file.txt

...

...

I'm not even sure which line it's trying to read when the exception gets thrown, whether it's the first line after "Waiting for Input: " or it's the line where I actually type something and hit return.

Any ideas why this might be happening? Could it have something to do with reading from System.in from a thread that is not the main thread?

Also, this is using java 1.6

[2634 byte] By [britty654a] at [2007-11-27 5:21:25]
# 1
the loop is trying to read when there is no line available from System.intry using read( byte[] ) and looking for a char sequence to end the loop and/or setting streamOpen=false when an exception is thrown
developer_jbsa at 2007-7-12 11:46:28 > top of Java-index,Core,Core APIs...
# 2
Shouldn't readline() be blocking until there is some input to read?
britty654a at 2007-7-12 11:46:28 > top of Java-index,Core,Core APIs...
# 3

> the loop is trying to read when there is no line

> available from System.in

> try using read( byte[] ) and looking for a char

> sequence to end the loop and/or setting

> streamOpen=false when an exception is thrown

This is mostly nonsense. readLine() will indeed block when there is no data available.

You must stop reading when either readLine() returns null or you get an IOException.

ejpa at 2007-7-12 11:46:28 > top of Java-index,Core,Core APIs...
# 4
So then the solution to continue reading after the IOException is to close the stream and re - open it and start reading again? (seems like a hack)A more ineresting question is why exactly is the bad file descriptor exception being thrown?
britty654a at 2007-7-12 11:46:28 > top of Java-index,Core,Core APIs...
# 5

> > the loop is trying to read when there is no line

> > available from System.in

> > try using read( byte[] ) and looking for a char

> > sequence to end the loop and/or setting

> > streamOpen=false when an exception is thrown

>

> This is mostly nonsense. readLine() will indeed block

> when there is no data available.

>

> You must stop reading when either readLine() returns

> null or you get an IOException.

more succinctly, you are reading after an IOException

maybe the os has a new fd for System.in

try recreating the stream reader after exception

developer_jbsa at 2007-7-12 11:46:28 > top of Java-index,Core,Core APIs...
# 6

Actually, restarting the stream doesn't work either..... here's a sample program that I wrote.

public class ExitListener extends Thread {

private BufferedReader br;

private boolean threadRunning;

public ExitListener(UbiBoardINRIA ubiBoard) {

super("Exit Listener");

threadRunning = true;

InputStreamReader isr = new InputStreamReader(System.in);

br = new BufferedReader(isr);

}

public void run() {

while (threadRunning) {

try {

String read = br.readLine();

if (read.equalsIgnoreCase("Exit")) {

threadRunning = false;

}

} catch (IOException ioe) {

System.out.println("Can you repeat that?");

try {

br.close();

br = new BufferedReader(new InputStreamReader(System.in));

} catch (IOException ioe2) {

ioe2.printStackTrace();

System.out.println("Killing this thread");

threadRunning = false;

}

} // end of catch

}

} // end of run

}

output:

...

I'm sorry, can you repeat that command? - Stream closed

Closed Stream

Ready?: false

I'm sorry, can you repeat that command? - Stream closed

Closed Stream

Ready?: false

I'm sorry, can you repeat that command? - Stream closed

Closed Stream

Ready?: false

I'm sorry, can you repeat that command? - Stream closed

Closed Stream

Ready?: false

...

I know that this is probably not enough code to really see the problem, but my main question is what could be going on somewhere else in the code that could cause this BufferedReader to not be able to re-open

britty654a at 2007-7-12 11:46:28 > top of Java-index,Core,Core APIs...
# 7
sorry, that's the wrong output, the REAL output is....can you repeat that? // this time it's because of "File Descriptor"can you repeat that? // this time and all the rest it's because of "Stream Closed"can you repeat that?...
britty654a at 2007-7-12 11:46:28 > top of Java-index,Core,Core APIs...
# 8
The systme never has a new fd for System.in, it is always zero, and I wouldn't expect reopening the stream after an exception to fix the problem .You need to stop after the first IOException and have a good look at the stack trace. Post it here.
ejpa at 2007-7-12 11:46:28 > top of Java-index,Core,Core APIs...
# 9

java.io.IOException: Bad file descriptor

at java.io.FileInputStream.available(Native Method)

at java.io.BufferedInputStream.read(BufferedInputStream.java:325)

at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)

at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)

at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:15

at java.io.InputStreamReader.read(InputStreamReader.java:167)

at java.io.BufferedReader.fill(BufferedReader.java:136)

at java.io.BufferedReader.readLine(BufferedReader.java:299)

at java.io.BufferedReader.readLine(BufferedReader.java:362)

at ubi.node.inputInterfaces.exit.ExitInputInterface.run(ExitInputInterface.java:32)

at ubi.node.inputInterfaces.exit.ExitInputInterface.startInterface(ExitInputInterface.java:69)

at ubi.node.inputInterfaces.InputInterfaceThread.run(InputInterfaceThread.java:15)

britty654a at 2007-7-12 11:46:28 > top of Java-index,Core,Core APIs...