get errorlevel in Java - java

I write the code in Java to launch specific application via command prompt. So the code will open cmd and run the application from there. I want to get the errorlevel of the execution. I tried with
String errorlevel = System.getenv("errorlevel");
System.out.println(errorlevel);
It always returns zero either the execution is failed or not. I also tried with getProperty() and came up with the same result.
Then the other way I tried
Process p = Runtime.getRuntime().exec(command);
int i = p.waitFor();
System.out.println("errorLevel :" + ""+ i);
With this, i get the exitValue but not exactly what I want since I have to close the application to retrieve the value
What I want to know is whether it is possible to get the errorlevel of commandprompt without exit/close the process manually
Thanks before

Related

How to make a process wait

I have a code that execute an external program. And now I need that my application wait the end of the execution of that external program.
But I'm not shure how I supposed to do that. I tried some things but don't work.
public Image acquireImage() throws IOException, InterruptedException {
process = Runtime.getRuntime().exec("cmd.exe /c start "+ApplicationProperties.getPath()
+ "\\.wimdesktop\\Release\\Static_GenerateGain.exe");
process.waitFor();
System.out.println("EXIT: " + process.exitValue());
return copyImage();
}
The problem is that the System.out.println("EXIT: " + process.exitValue()); print 0 but the external program still running.
You are running cmd.exe and asking it to start a process in the background. So all you are seeing is cmd.exe exit status 0 after it launches your app - and that app may still be running.
If you want waitFor to apply to the sub-process just run the exe directly without the launch wrapper:
process = Runtime.getRuntime().exec(ApplicationProperties.getPath()
+ "\\.wimdesktop\\Release\\Static_GenerateGain.exe");
Note that if your EXE depends on environment variables set by CMD.EXE then you may need to try your original command without "start" for background process:
process = Runtime.getRuntime().exec("cmd.exe /c "+ApplicationProperties.getPath()
+ "\\.wimdesktop\\Release\\Static_GenerateGain.exe");
In both cases above you may run into second issue that the command freezes, this is because you are not reading the Stdout and error streams. There are many SO posts on how to do this.

How to wait for multi-threaded shell script execution to finish called inside my web service?

I have a java restful service method which executes a myscript.sh using processBuilder. My script takes one input (example - myscript.sh /path/to-a/folder).
Inside the script something like this
-> execute a command which is multithreaded i.e parallel processing
-> echo "my message"
Now when call my script from a linux command line it executes fine. First all the threads running finishes and then some text output from threaded command execution shown on terminal and then echo my message is shown.
But when I call the same script from java using processBuilder, the last echo message comes immidiately and execution ends.
Following the way I call my script from java
ProcessBuilder processBuilder = new ProcessBuilder("/bin/bash","/path/to/myscript.sh","/path/to/folder/data");
Process proc = processBuilder.start();
StringBuffer output = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while((line = reader.readLine()) != null){
output.append(line + "\n");
}
System.out.println("### " + output);
I don't know whats happening, how to debug also.
Can someone enlighten me on how to get the same behaviour from shell script when run from terminal or from java processBuilder?
Use ProcessBuilder.redirectErrorStream(boolean redirectErrorStream) with argument true to merge the errors into output. Alternatively, you could also use the shell command syntax cmd 2>&1 to merge the error with output.
These are some of the cases why you may be immediately getting the output of the last echo statement (instead of the script taking time to run and return proper results):
Missing environment variables
The launched bash needs to source .bashrc or some such recource file
The launched bash may not be running in right directory (you can set this in ProcessBuilder)
The launched bash may not be finding some script/executable in its PATH
The launched bash may not be finding proper libraries in the path for any of the executables
Once you merge error, you would be able to debug and see the errors for yourself.
In your context, separate processes may be spawned in two ways:
1) Bash
/path/to/executables/executable &
This will spawn a new executable executable and you need to wait for it to finish. Here's an answer that will help you.
2) Java
Process exec = Runtime.getRuntime().exec(command);
status = exec.waitFor();
Essentially, you need to wait for the process to end before you start reading its std/err streams.
If I understand the problem correctly, adding just this line to your code should suffice: status = exec.waitFor() (Before you obtain the streams)
Here's the JavaDoc for Process.waitFor() :
Causes the current thread to wait, if necessary, until the process represented by this Process object has terminated. This method returns immediately if the subprocess has already terminated. If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.
Returns:
the exit value of the subprocess represented by this Process object. By convention, the value 0 indicates normal termination.
Throws:
InterruptedException - if the current thread is interrupted by another thread while it is waiting, then the wait is ended and an InterruptedException is thrown

Calling perl from java

How do I call a perl script from java? Currently I have this code but a create process error =2 keeps coming up.
Process p = Runtime.getRuntime().exec("perl C:/Users/Mahish/Documents/PLUa/src//test.pl");
You need to set full path to your dir perl\bin
Example command to do this in CMD:
SET PATH=%PATH%;c:\perl\bin
and after that you can use:
Process p = Runtime.getRuntime().exec("perl C:/Users/Mahish/Documents/PLUa/src/test.pl");

Get exit value of CMD child process called from java program

In my java program I am trying to run a different program through CMD with its output appearing in a command window in the foreground and then analyze the exit code of the child program (foo) in the main java program. Unfortunately, all I seem to be able to access is the exit code of the CMD window, which is always 0.
The following is a snippet of what I'm doing:
ProcessBuilder pb = new ProcessBuilder();
pb.directory(new File(dir));
pb.command("cmd","/c","start","/wait","foo.exe",arg);
process = pb.start();
exitVal = process.waitFor();
but exitVal is always 0 regardless of how foo exits. How can I get just the exit code of foo?
I'm also pretty new to java so if there's a more elegant way of doing this, I'm open to suggestions.
I found a solution by modifying one of the things I had tried before to account for windows batch being finicky. The solution was to send another command to cmd to tell it to exit with the most recent error code. Earlier I had tried this by appending & exit %errorlevel% to the command but cmd variables are only updated at the end of each command line, not at the end of each command.
To force update, I used %^errorlevel% instead.

Run bat file in Java and wait

You would think that launching a bat file from Java would be an easy task but no... I have a bat file that does some sql commands for a loop of values read from a text file. It is more or less like this:
FOR /F %%x in (%CD%\listOfThings.txt) do sqlcmd -Slocalhost\MSSQL %1 %2 -d %3 -i %CD%\SQLScripts\\%%x
exit
Don't worry about the specifics they are not important. What i want is to simply run this bat file from within Java and have it wait until execution is finished. Apparently it is not easy. What i have so far is this:
Runtime.getRuntime().exec("cmd /K start SQLScriptsToRun.bat"
+" -U"+getUser()
+" -P"+getPass()
+" " + projectName);
return true;
The problem is that the exec() method returns immediately. The bat file runs for a good 2-3 minutes. I tried removing the start but to no avail. I tried many variations but it got me nowhere. Any ideas on how to do this simple task?
You should not ignore the return value of .exec(). It gives you a Process object that you can waitFor(), like this:
final Process process = Runtime.getRuntime().exec("blahblahblah");
final int exitVal = process.waitFor();
// if exitVal == 0, the command succeeded
you need to use waitFor on the process exec call returns.

Categories