File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes Runtime exec...and br hanging Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Runtime exec...and br hanging" Watch "Runtime exec...and br hanging" New topic
Author

Runtime exec...and br hanging

Sergi Bradley
Greenhorn

Joined: Feb 19, 2003
Posts: 12
I am trying to write a simple gui that calls MPlayer which is a linux media player. The Execute Command class will start and execute the command "mplayer somefile.mp3" and it will play.
I write "p" to output stream and the music pause, after i try to unpause it...it is like the inputstream and errorstreams are stuck at the readlines in their respect class. This same thing happens when i write "m" to output stream to mute it, the threads just lockup or something and no more output is written to stream. I am out of ideas...below is my code. After i seen the "p" or "m", i send another "p" or "m" to unpause or unmute the player...however nothing ever happens...it like the two classes lockup..below is my code.thanks for all
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Hmmm... normally the problem here would be if you didn't use separate threads for input, output, and error - but it seems you've covered that already.
I don't see exactly how you're sending the "p", "m", etc - the outputToConsole shown is just "". It may be that even if you send "p" you need "\r\n" after to complete the command to the media player; dunno. Does that help any?


"I'm not back." - Bill Harding, Twister
Sergi Bradley
Greenhorn

Joined: Feb 19, 2003
Posts: 12
I have a gui that just fires an event to this class. So when i press pause it changes the field outputTOconsole to some string other than "". I write that to standard out. One first time i do this, it works fine...one 2nd to infinite time i do this it fails...it is like all 3 streams are stuck...it seems that it write to the output stream, because an exception is never thrown and the method finishes. However it seems that it is just writing to a dead process, because nothing happens.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Hunh - weird. You might try changing all those catch statements to catch Throwable (just for debugging at least) and add finally{} clauses to each checkForXXX() method to be more certain that each of those methods is still in a loop as expected. Might give you some useful info. Good luck...
Sergi Bradley
Greenhorn

Joined: Feb 19, 2003
Posts: 12
But none of my execption are being thrown....i wish they were. It is just stalling at the readLine, it is like they are timeing out...man this is driving me nuts....thanks for the help so far thought...more ideas please
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Hi Sergi,
I currently don't have access to a Linux box, so I have no way to test a couple of hunches. First, as an afternoon's perusal of Java's bug parade will show, Process' IO Pipes are extremely flakey. One point that comes thru is that you must be sure to consume everything that comes out of the the process' stdout and stderr or the pipe will fill and block forever. Going thru your code it appears as though you are doing that, but there is a possibilty since you are using a busy wait ie while(true) { this.checkForOutput(child); }, that the two consuming threads are not able to keep up with the process output. I would suggest that you try something like this:

Now to get the thread out of the wait pool, I would suggest that you have your class implement Observer and call notifyAll() in the update() method. You would have to register with an Observable, presumably somewhere in your GUI that knows when outputToConsole has changed.
Hope this helps,
Michael Morris


Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
Sergi Bradley
Greenhorn

Joined: Feb 19, 2003
Posts: 12
So the exeecutecommand class is the observable and the class sending the output is the observer. Should i create a seperate thread to take output.
I am confused, if the executecommand waits, how can i update the field, that will throw an illegeal monitor execption wont it. Please explain, this sounds like a good idea.
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Hi Sergi,
You'll have to synchronize the execute() method and the update() method. I want to emphasize that this is only a hunch. I'm also having a similar problem with Runtime.exec() and Process. I'm looking into the new java.nio package to solve the problem. If I come up with anything, I'll let you know.
Michael Morris
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Something just occurred to me - what if one of the streams you're waiting for has outputted something that doesn't end in a line terminator? E.g. "Do you wish to continue (Y/N): " and the cursor is supposed to be sitting at the end of the line, waiting for your input? The readLine() methods you're using are waiting to see a line terminator before they continue, and won't show you anything until that happens. So perhaps replace those loops with something like:

This might look a little ugly, with some funny breaks in long lines - but it should guarantee you're really seeing everything that's appeared in the InputStream.
But none of my execption are being thrown
Are you sure? You're checking for IOException - but what if an Error or RuntimeException is thrown? Usually these uncaught exceptions will result in a nice obvious stack trace, but I have vague memories of managing to accidentally disable this feature without realizing it, a few times in the past. I think it was when I was calling a method from within the GUI event handling thread - an Error was being thrown somewhere, and the error message either wasn't appearing at all, or wasn't where I expected to find it. (I've also managed to redirect my error output a few times and then forget that fact.) It can't hurt to put in some extra sanity checks in your code at this point.
[ February 20, 2003: Message edited by: Jim Yingst ]
Sergi Bradley
Greenhorn

Joined: Feb 19, 2003
Posts: 12
Well i tried your printing method and it did not cure the problem...however it was a good idea.
How about do u go catchig runtime exception in your code...i need a print the stacktrace somehow.
But i do believe u are on to something about the process is not getting terminator, reason if i write a stop command(i write 'q") to the process...the thread will die. But if i send anything else..i get the lockup..
below is the final output when i try to pause it...

pause

pause pressed
PAUSE SIGNAL SENT
A: 1.1 2.0% 0%
A: 1.2 2.0% 0%
Process in INPUT: A: 1.2 2.0% 0%
Process in INPUT: A: 1.2 2.0% 0%
Process in OUT : p
A: 1.3 2.0% 0%
================= PAUSED =================
pause pressed
UNPAUSE SIGNAL SENT
Process in OUT : p
pause pressed
PAUSE SIGNAL SENT
Process in OUT : p
pause pressed
UNPAUSE SIGNAL SENT
Process in OUT : p

after the above pause line...is where is just stalls on reading anymore lines or character from either the in or the error...reguardless of how many times i try to write back to the outstream
stop
Process in OUT : q
Process in INPUT: A: 1.1 1.7% 0%
Exiting... (Quit)

stop command produces the correct output because if ran in a terminal u would get your prompt back as such
Starting playback...
A: 1.2 1.9% 0%
Exiting... (Quit)


Thanks to all how have replied so far
[ February 20, 2003: Message edited by: Sergi Bradley ]
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Hi Sergi,

How about do u go catchig runtime exception in your code...i need a print the stacktrace somehow.

Just change the catch block to catch RuntimeException, Exception or even Throwable.
There was a known problem and work around posted on this subject about a year ago, but I can't find it here or at java.sun.com. I'll keep looking.
Michael Morris
Sergi Bradley
Greenhorn

Joined: Feb 19, 2003
Posts: 12
No dice...changed everything to Exception, but came up short...i feel like i am missing something small....so close.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Change it to Throwable. That way you catch Errors too. Yeah, you're usually not supposed to do this unless you know what you're doing, but if your program is locking up anyway you're not really going to make things any worse. And I'm just talking about for debugging purposes - change it back later when the problem is solved.
Sergi Bradley
Greenhorn

Joined: Feb 19, 2003
Posts: 12
Yeah.. i changed it to throwable as welll...i aint getting any exception thrown. Debugging really hurts the head...i think i am going to do a little rewritting of this tomorrow....my head hitting keyboard is starting to hurt
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Hi Sergi,
I'm beginning to think that the IO streams from Process are just unpredictable. I've been working on a remote shell for Windows 2000. I was having a similar problem to yours, the damn thing just hangs for no apparent reason. At least on the machine I was testing on. I brought it home and it runs like a charm. Both machines have identical versions of Windows and JRE. So, go figure. Here's my code if you care to look at it:
RSHServer.java

ConnectStreams.java

Michael Morris
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
OK, either I lied or the elves came in and fixed the code over night. Now it works on both machines. There is a problem when a client tries to exit the shell though. The stdout and stderr objects both close down without a hitch, but the stdin object continues to block waiting for an EOF marker which the client socket never issues because the socket is still open.
Anyway, now I'm not sure if my problems were related to Sergi's especially since there is a diffence in OS's and a difference in standard output and input, text for Windows and binary for linux.
Michael Morris
Sergi Bradley
Greenhorn

Joined: Feb 19, 2003
Posts: 12
HOw does your the obserable work...i guess it is like an event listerner. Would u care to explain how that works? I am trying to use some of your ideas here...and i just fail to understand the observor.
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Hi Sergi,
The class ConnectStreams extends java.util.Observable so when the its run() method finishes the finally block is called:

Observable.setChanged() indicates that this has changed and Observable.notifyObservers() calls the update() method on all registered Observers.
We registered in RSHServer, which impements java.util.Observer, like this:

It is definitely like an event callback.
Note that I have changed my update() method and if you like, I'll post it tomorrow. I still don't know what's causing your problem though. I was going to put Mandrake 9 on my machine this week but am having hell with Partion Magic, but that's another story. If I ever get Linux up and running again, I'll try your code and see if I can figure something out.
Michael Morris
Sergi Bradley
Greenhorn

Joined: Feb 19, 2003
Posts: 12
Yea i threw some println in, and i kinda figured out the obererver, pretty cool. Thanks for that one...
Now i think i know what is going wrong. When i try to pause the program, it pauses. Well the process does not send anymore input or error to the stream...so the streams just die. So, where to go from there i am not sure.
Here is another thing i noticed, if i dont read the input, the app crashes...but that has to do with the buffer being filled up..right.
Sergi Bradley
Greenhorn

Joined: Feb 19, 2003
Posts: 12
Horray....i figured it out...and learned some stuff in the process.
Well, here was the problem...it was the programmer(haha i have to laugh at myself).
I was closing the stream after i wrote the first time. Thus any attempts after that was null and void.
I did clean up my classes, i wrote them kinda like that code u supplied. Here is the code for the new output stream. I just create this runnable anythime i need to write to the outstream... i left the bad code commented out...
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Horray....i figured it out...and learned some stuff in the process.
Excellent news. Thanks for letting us know what happened. I'm used to asking people "did you remember to close the stream?" - it's worth remembering that closing a stream too early can be bad too.
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Glad you got it fixed.

...but that has to do with the buffer being filled up..right.

Just take a ride thru the bug parade and see how many bug reports have been filed on that one! Only for the reviewer to close the report with something like "This is not a bug, if a process has output, that output must be consumed".
Michael Morris
Sergi Bradley
Greenhorn

Joined: Feb 19, 2003
Posts: 12
thanks again...for all the help.
 
Don't get me started about those stupid light bulbs.
 
subject: Runtime exec...and br hanging
 
Similar Threads
running a batch file from java
calling unix application mplayer
runtime exec - mplayer doesn't complete
who can my question about this code
Process err- not a valid Win32 application