Running program with subprocesses with Java - java

I need to run an external program written in C from my Java application.
I'm trying to use Runtime.getRuntime().exec() with partial success. I execute program using String with path to .exe file and its arguments:
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command);
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line=null;
while((line=input.readLine()) != null) {
log.info(line);
}
int exitVal = pr.waitFor();
This would work just fine - program executes and sends information about its behavior to console. Problem is that external program tries to run other subprograms during its execution. So basically what I need to do is: I run program.exe with my Java application and program.exe runs subprogram.exe. Unfortunately, that's not the case, because subprogram.exe never starts in current situation.
What should I do differently to make it work ? Thanks for any help.
It is not my decision to have it so complicated and I would be more than happy to have just one .exe file to execute, but I can't.

Try to run it from cmd.exe i.e.the command prompt and see if its working well.The console output should give you a trace of the program execution.

Related

Java Shell Command not Running from Current Directory

In this question it shows that when you run a shell command from Java, it runs from the current directory. When I run the command javac Program.java from my program, it shows the error (from the standard error stream):
javac: file not found: Program.java
Usage: javac <options> <source files>
use -help for a list of possible options
However, when I run the same exact command from the actual Terminal, it works fine and saves the .class file in the default directory. This is the code:
Runtime rt = Runtime.getRuntime();
String command = "javac Program.java";
Process proc = rt.exec(command);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
proc.waitFor();
Any ideas why it works when I type it in the actual Terminal, but not when I run it from my program? I am running a Max OS X Mountain Lion (10.6)
Thanks
You can try to print the path in your programm ,use new File(".").getAbsolutePath() ,if you are in a ide ,the path may be in the root of the project rather than in the path of the current java file
Your program is probably being run from a different directory. Your IDE (such as Eclipse) is probably is running from one location, and knows the directory structure to access your program files.
The easiest, quickest solution is to just write the fully-qualified file path for Program.java.
The alternate is to find out what the current directory is. So, perhaps run pwd the same way you are running javac Program.java from within your program's code? Then you can see what directory your program is actually being run from. Once you know that, you can write the appropriate directory structure.
For example, if pwd reveals that you are actually 2 directories above where Program.java is, then you can put those directories in the command like this: javac ./dir1/dir2/Program.java.
To change the directory Eclipse runs from, see this question Set the execution directory in Eclipse?
The reason my code was not working was because I was running it in Eclipse IDE, and that messes up the directory the program is running from. To fix that program, I changed the command to javac -d . src/Program.java. If I export the program into a .jar file and run it in the desktop, my original command will do just fine.
Thanks to saka1029 for helping me!

How to access linux command such as sed,awk from java

I have been studying JNI (Java Native Interface) since last month.It is really interesting .I mean call Java functions from C and vice versa.Now I have an intention call linux command which I mentioned above like sed,awk from Java side.also I have a little bit knowledge about Sell Script in linux. please give me some hint how to do this.
You should Runtime.exec() or ProcessBuilder depending on what you require to execute process into your local system.
This questsions could help:
difference between ProcessBuilder and Runtime.exec
Java Runtime.exec()
You could use this java snippet to run a shell command:
Process process = Runtime.getRuntime().exec("echo This is a test"); //Start the process
process.waitFor(); //Wait for the process to terminate
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); //Get the output

How can I run a bash script (which downloads a file) in Java?

Running in Mac OS X Lion, I need to retrieve a file from a remote server using a script in the command line. The command I'm trying to use in code is "bash /my/path/here/myscript" and I already run another process from the command line (atos) using the code below.
Process proc = Runtime.getRuntime().exec(cmd);
But while debugging, the program continues without error, yet the script does appear to have actually run. Furthermore, there should be a pause of several seconds while the script retrieves the file, yet my program continues to execute immediately. The script itself works as intended when run from the terminal. I'm a little stumped on how to get this to work, so any help would be greatly appreciated.
Got it to work with the following code -
Process proc = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
proc.waitFor();
while (in.ready()) {
System.out.println(in.readLine());
}
The other thing that was an issue is that the script would download to the current working directory rather than the location of the script itself (as intended). So the script would run correctly while my program would continue to fail to find the downloaded file. Hope this helps.

Java - Executing commands into a batch file

I have made a java script which uses the runtime.exec() to execute a batch file, and that works fine but when i get the output stream and use the write() function it does not execute the command i put into it.
Runtime runtime = Runtime.getRuntime();
Process p;
p = runtime.exec("cmd /c start batchfile.bat");
out = p.getOutputStream();
out.write("command".getBytes());
It displays the batch file but does not run the command, is there another way of entering a command into the cmd running the batch file so it displays it?
With the start command, a separate command window will be opened, and any output from the batch file will be displayed there. It should also work as just cmd /c build.bat, in which case you can read the output from the subprocess in Java if desired.
You're writing into an output stream. I think you mean to write to an input stream.
Try this:
Runtime runtime = Runtime.getRuntime();
Process p;
p = runtime.exec("cmd /c start batchfile.bat");
in = p.getInputStream();
in.write("command".getBytes());

Powershell process hanging when called from Java application

I am trying to write a simple application that takes in a command line arguement (which will be a Powershell ps1 file) and then run it. So I have experemented with a number of different approaches and seem to be running into a problem. If I attempt to invoke powershell from within java, the windows process is started and is visible via process explorer, however powershell never returns, it hangs in some sort of loop by the looks of it. The command I am using is:
String command = "powershell -noprofile -noninteractive \"&C:\\new\\tst.ps1\"";
The command is then executed using:
Runtime systemRuntime = Runtime.getRuntime();
Process proc = systemRuntime.exec(command);
At the moment I am hard coding the location to the ps1 file as I was trying to rule this out as an issue. Using a process explorer I can see the hanging powershell process and the command that was passed to it was :
powershell -noprofile -noninteractive "&C:\new\tst.ps1"
which when copied into a cmd window, works to launch the tst.ps1 file. The file itself is incredibly simple in this example and I think I can rule it out being the cause of the freeze as I have tried to launch other ps1 files the same behaviour can be seen.
To further add to the confusion, if I use the java code posted above and pass in powershell commands instead of a file name then it successfully runs.
I've scoured the web and see lots of people experiencing the same issue but no one seems to have posted there solution, I hope its a simple oversight on my part and can be easily fixed.
Any hints/tips are appreciated :D
Alan
You have to close OutputStream in order for Powershell to exit.
Runtime systemRuntime = Runtime.getRuntime();
Process proc = systemRuntime.exec(command);
proc.getOutputStream().close();
Is your external program writing to the standard outputs (err and out)?
If yes, it can hang waiting for you to consume them from the java parent process.
You can get those as InputStreams by calling
Process.getInputStream()
and
Process.getErrorStream()
There's more details here:
Javadoc for Process

Categories