Java runtime.exec causes program crash - java

I am trying to run an external program Decoder.exe using a java:
Runtime.getRuntime().exec("C:\fullpath-and-so-on\Decoder.exe -h"); like so:
try{
Process p = Runtime.getRuntime().exec("C:\\fullpath-and-so-on\\Decoder.exe -h");
}
catch(Exception e){
e.printStackTrace();
}
This works for all other programs I've tried. But whenever I execute it from java the Decoder.exe crashes. The java executes fine and does not generate any exceptions but the called program Decodes.exe stops working. The program Decoder.exe executes perfectly when run in a separate cmd window.
Have anyone had any experience with a similar problem? What differs when java runs exec and when a program is run in cmd.exe? Is there a known workaround or am I just making a mistake somewhere?
Very thankful for any help!
BR,
Fredrik

Stops working you say?
Is the decoder.exe writing output to stderr or stdout? You must in that case read those streams, since the buffers for the streams are very small, and the execution will halt if those buffers get full.
This is a great article, it's old, but it still holds:
When Runtime.exec() won't

this tutorial can help you with that http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1
and
ProcessBuilder
and
Oracle API
maybe my question Pass String as params from one Java App to another

Related

How do i launch a GUI Terminal and run commands on it in java

I have a program which runs when you double click it. What i want to do is:
Double click a jar File
Launch some GUI
And Run Commands in the terminal through the java program
(just an example, this is not what i want to do)
I Tried this:
public class Main{
public static void main(String [] args){
Runtime.getRuntime().exec("/bin/bash sudo SOME_COMMAND_HERE");
}
}
(SOME_COMMAND_HERE is just a replacement)
It didn't launch a terminal.
(i have the GUI part so no need to write code for that)
So how do i do this? I have been spending a past day or two for just finding answers on stack overflow, and intense googling.
Plus the Reason why i need it is because i want to show the user some progress and entering the password when running sudo commands.
Can some Please help? Thanks in advance.
In your example the process might get stuck as you are not reading it's stdout and stderr streams. From the Process documentation:
Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the process may cause the process to block, or even deadlock.
So essentially you are just asking how to execute a process from Java. It is irrelevant that to the user your program would display a terminal-like UI. Knowing this we could rephrase your question and find answers like
Starting a process in Java?
Java Execute a bash script using Java process builder
Execute process from Java irrespective of underlying OS
Java ProcessBuilder - get Output immediately
https://alvinalexander.com/java/java-exec-processbuilder-process-1/

Using java Process builder to play wav file

I would like to send the following command below from a java program, but not overly bothered about reading the response. any idea how I can do this
the command below plays the wav file from the command prompt
aplay ~/javafx/examples/PrayerTime/src/Audio/athan1.wav
I am trying the code below but it is not playing anything! from my java program
ProcessBuilder processBuilder = new ProcessBuilder("bash", "-c", "aplay ~/javafx/examples/PrayerTime/src/Audio/athan1.wav");
try {
Process process = processBuilder.start();
} catch (IOException ex) {
Logger.getLogger(JavaFXApplication4.class.getName()).log(Level.SEVERE, null, ex);
}
Andrew is absolutely right when he writes ignoring the output is the core of the problem.
When you start a process via processBuilder.start(), you are basically launching another process that has a life of its own. It's fire and forget. The only feedback you get via thrown exceptions is when the actual lauching didn't succeed. It says nothing about whether the launched process succeeded in what it was supposed to do.
Since you don't see an error message, the launching of the process went fine.
Now, using aplay and ~ suggests, that you are on some kind of Unix, probably Linux. There a process prints regular output to the standard out stream and error output to standard error stream. It also returns an exit code, that indicates whether things went smoothly or not. Both the exit code (you can get it from the process object by using waitFor()) and the error stream (also available from the process object) give you all the necessary info whether a process succeeded and if not, why not.
That all said, you might really want to use Runtime.exec() as it is much less complicated—at least until you know how to call your process without error.

Running R script from Java

I have a R script I need to call from Java and run. I tried this code: Runtime.getRuntime().exec("Rscript pathTo/R/myScript.R"). I run it from windows command it worked fine, but when I run java class with this code in Eclipse, nothing happens. The console doesnt show anything no error no logs. Can someone tell me how to run this script from Java?
By default, a Process launched from java has its standard input, standard output and standard error redirected to pipes, which you can access from within java. Unless you read from the standard output and error pipes and transfer the text to the output of the Java application yourself, no output will become visible. Furthermore, if the internal buffer of the pipe gets full, then the child application might even block while waiting for root to write its data. So the process probably will hang and never terminate.
Since Java 7, you can have the child process inherit its I/O channels from your Java application using ProcessBuilder.inheritIO. That saves you all the trouble to read from those streams yourself.

Java receives an error executing Ruby script; Terminal doesn't

This is a forked problem off of this question: flac: "ERROR: input file has an ID3v2 tag" (it doesn't). I've solved the initial issue there but that didn't resolve one problem I was having, so I'm going to introduce it separately here.
I'm using a Ruby gem called speech2text to convert an audio file into (approximated) text. Calling it on the command line works fine (Mac Terminal). However, the following Java code:
String[] cmd = {"speech2text", "tmp/audio/pop-test-audio.wav"};
ProcessBuilder builder = new ProcessBuilder(cmd);
builder.redirectErrorStream(true);
Process process = builder.start();
Only receives this back from the process streams:
/Library/Ruby/Gems/1.8/gems/speech2text-0.3.4/lib/speech/audio_inspector.rb:50:in `initialize': undefined method `first' for nil:NilClass (NoMethodError)
from /Library/Ruby/Gems/1.8/gems/speech2text-0.3.4/lib/speech/audio_splitter.rb:77:in `new'
from /Library/Ruby/Gems/1.8/gems/speech2text-0.3.4/lib/speech/audio_splitter.rb:77:in `initialize'
from /Library/Ruby/Gems/1.8/gems/speech2text-0.3.4/lib/speech/audio_to_text.rb:15:in `new'
from /Library/Ruby/Gems/1.8/gems/speech2text-0.3.4/lib/speech/audio_to_text.rb:15:in `to_text'
from /Library/Ruby/Gems/1.8/gems/speech2text-0.3.4/bin/speech2text:11
from /usr/bin/speech2text:19:in `load'
from /usr/bin/speech2text:19
I don't know anything about Ruby, hence my lightweight use of the library through Java. I really can't tell what's going on here, but I know that it works when executed in exactly the same way from the Terminal. Has anyone got any idea what might be causing this?
You could also ditch the terminal and try JRuby. It's just as fast as the normal Ruby VM and is easier to integrate with Java.
I have had similar issues trying to run jslint.js (for node.js). I actually did better running bash first, then print writing in my commands that way, but even that had problems as I recall.
Basically the problem is that executing things with Java can fail when environment settings that would otherwise be available are not loaded. This can be a tough one to solve.

Running a continuous batch process in Java

I have a batch file which performs the operation of listening to the microphone and converting it to text (i am using pocket sphinx).
The command I am using to run the batch file is pocketsphinx_continuous.exe -dict <dict name> -lm <language model> -hmm <acoustic model location>. The batch file starts off and keeps listening to the microphone. Whenever we finish speaking a sentence it converts it into text on the command prompt. Since this continuously running we terminate this task by Ctrl-C.
I was trying to make this into a standalone Java application. I wanted to run this batch file through Java, so i used Runtime.getRuntime().exec("cmd /c start pocketsphinx_continuous.exe ...") with all the parameters. However strangely, it starts the batch process in a separate command prompt but immediately exits. I tried to use process.waitfor(), however it simply starts executing the batch process and then terminates. I havent called process.destroy, so i am unable to figure out why it exits the batch process.
The other question is since the batch file is running continuously, after every spoken sentence has been transcribed , I wish to get the output in my Java application. I know i can redirect the batch process to a file and then read the file, was just wondering if there is a more direct process. Could you please help me figure out where I am making a mistake.
You should use Process.getInputStream() and Process.getErrorStream() to find out what messages it prints out.
If it is exiting instantly, you might need to get the exit code (Process.waitFor()) and check the error logs from the error stream.
Also, if you can post some of your code we might be able to help. In general, these problems are due to incorrectly configured paths or command strings.
A possible fix would be to use the ProcessBuilder from Java 1.5 thusly:
// Note the lack of "cmd \c" - you shouldn't need to run it in a cmd window!
ProcessBuilder pb = new ProcessBuilder("pocketsphinx_continuous.exe",
"dict", "1121.dic",
"-lm", "1121.lm",
"-hmm", "hub4/hmm");
Process p = pb.start();
// TODO for you:
// 1. Create Threads to handle the input
// 2. Store the Process instance so that you can call p.destroy() later.
// 3. If interested, have a Thread doing p.waitFor() to get the exit code.
As Joachim Sauer mentioned in the comments, this Javaworld article explains a lot of the gotchas associated with the Process API, so have a read through. I haven't had a chance to play with the improvements made in JDK7 to the Process API, and by the looks of things Oracle are improving it again for JDK8 (JEP 102).
You can also use Timer and TimerTask to schedule your batch scan process in background. You can use this to specify infinite running task.

Categories

Resources