This week's book giveaway is in the Clojure forum.
We're giving away four copies of Clojure in Action and have Amit Rathore and Francis Avila on-line!
See this thread for details.
Win a copy of Clojure in Action this week in the Clojure forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Printing using Runtime.getRuntime().exec()

 
Kelly Michaels
Greenhorn
Posts: 14
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello list, I am a newbie and I'm confused even after reading a lot about it. Bear with me please. I am trying to print using a print server using command level options (lp file.pdf -h xxx.xxx.ip.xxx -d Printer_id). When I issue a command at a terminal, i see message saying 'the file has been sent to the printer'

I used Runtime.getRuntime().exec() to send the above command and everything works fine. But I read articles http://vyvaks.wordpress.com/2006/05/27/does-runtimeexec-hangs-in-java/ on how I am supposed to "write the input stream or read the output stream of the subprocess" and failure to do so would cause my process to hang.

Since I am just issuing a command and don't really care for the 'the file has been sent to the printer' message, do I still need to "write the input stream or read the output stream of the subprocess" OR is "Runtime.getRuntime().exec()" good enough? Thanks guys.
 
Rob Spoor
Sheriff
Pie
Posts: 20393
46
Chrome Eclipse IDE Java Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When Runtime.exec() won't is another article about the hanging problem. The short answer to your question: yes, you still need to read the output stream (and error stream!) from the process, even if you don't need to wait for it. Otherwise the process will try to write to the buffer, it can't, and it will still block.
 
Kelly Michaels
Greenhorn
Posts: 14
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Rob. I was reading through your article and I have a question on page 4 http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4,

GoodWinRedirect.java

Since I don't care about the output, do I need to code the line "int exitVal = proc.waitFor();"

// kick them off
errorGobbler.start();
outputGobbler.start();

I think I should stop after the above code, correct? Just want to double check. Thanks again. I appreciate your help
 
Rob Spoor
Sheriff
Pie
Posts: 20393
46
Chrome Eclipse IDE Java Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Right. You don't need the exit code, so as soon as you start the buffer-emptying threads you're done. These threads will die automatically once the process stops.
 
Campbell Ritchie
Sheriff
Pie
Posts: 47293
52
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch
 
Kelly Michaels
Greenhorn
Posts: 14
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks guys :-)
 
Kelly Michaels
Greenhorn
Posts: 14
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi again, I read the error and output streams and almost 90% of the time, the program works fine. But once in a while it still hangs in the callPrinter method. Is there something else I am missing? Any pointers, suggestions would be greatly appreciated!

 
Campbell Ritchie
Sheriff
Pie
Posts: 47293
52
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What have you done that is different from Michael Daconta's suggestions?
 
Kelly Michaels
Greenhorn
Posts: 14
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell, Thanks for responding.

As far as I understood the article, I didn't code


because he had mentioned on Page 2 "The only possible time you would use exitValue() instead of waitFor() would be when you don't want your program to block waiting on an external process that may never complete."

And I didn't want my program to wait on the external process. I just wanted to submit the commands and move on. So I didn't code the exit code.
 
Campbell Ritchie
Sheriff
Pie
Posts: 47293
52
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are you confusing the input stream and the output stream? Look at the constructor call for your second StreamGobbler object.
 
Rob Spoor
Sheriff
Pie
Posts: 20393
46
Chrome Eclipse IDE Java Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nope, that's correct. The process' getInputStream() method returns an InputStream to read the output of the process.
 
Kelly Michaels
Greenhorn
Posts: 14
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Initially I was confused too, but what Rob said was also explained in another thread.

For the heck of it, I did a after the in the run() method. I don't think I need a , Do i?
It still hangs once in a while though. Thanks guys.
 
Rob Spoor
Sheriff
Pie
Posts: 20393
46
Chrome Eclipse IDE Java Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
br.close() closes isr as well.
 
Kelly Michaels
Greenhorn
Posts: 14
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I came across something called async beans and I was wondering if putting the Runtime..exec() code as an async bean would not cause the main thread to hang. I tried googling for a simple example of an async bean and I can't find one easy enough to understand. Could you guys point me to resources that will help me convert the above method to an async bean? Thanks again.
 
Kelly Michaels
Greenhorn
Posts: 14
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please ignore my previous question. I didn't know how to delete my post.
 
Campbell Ritchie
Sheriff
Pie
Posts: 47293
52
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can't delete posts. I can, but I for one (opinions vary) would sooner have a post remain, even with an "ignore" annotation, than delete it.
 
Kelly Michaels
Greenhorn
Posts: 14
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell, Thanks. I have modified my code to make the Runtime..exec() a thread on its own. And I have a couple of questions about this version
1) My parent thread implements Runnable and the child thread subclaases Thread. Will this mix and match cause a problem?
2) I have commented in the StreamGobbler constructor. But since I don't care about the OUTPUT or the ERROR message coming back from Runtime.getRuntime().exec(), can I make StreamGobbler a daemon thread. I am afraid if this remains a user thread and finds a way to hang itself, the rest of the application will hang as well. Here's the modified code and thank you very much for your feedback guys. I sincerely appreciate your time.



And this is how I start the parent thread:
 
Campbell Ritchie
Sheriff
Pie
Posts: 47293
52
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Don't know. I don't think you can do any harm by making your threads daemons; they will simply stop whenever the streams stop sending any information. Can you think of any way a thread which simply empties a stream could hang, however?
 
I agree. Here's the link: http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic