I have one swing application from which I am executing one jar file, which will do some processing internally. Process I have is as below:
1. one java file with main() which loads swing GUI. From that GUI I can browse and load required jar files to execute.
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
MigrationProcessElementDialog.createAndShowGUI();
}
});
}
From swing application I am loading jar file as:
Runtime rt = Runtime.getRuntime();
// replacePath is the path of the jar file to be loaded.
Process proc = rt.exec("java -jar " + replacePath);
int exitVal = proc.waitFor();
When I trigger execution, from Task Manager I am seeing, two javaw.exe (one for eclipse, one for SWING GUI) and one java.exe for program flow.
But program flow continues few times (evident from log update) but stuck after certain time.
As soon as, I kill my swing GUI javaw.exe; program flow starts and continues rest of the part promptly. So it seems to me that somehow javaw.exe is blocking java.exe execution. Is it at all possible? what's the resolution of it?
If I execute, my process executable jar from command prompt using normal java -jar "path" command, program flow is not stuck, it's working as expected.
Only facing the problem when I am executing from GUI or using Runtime. I used ProcessBuilder also; but faced same problem.
If any one can please give me any clue it will be really helpful. Thanks!
You should handle output of process (both of stdout, stderr ). Because, these outputs will be redirected to the parent process through three streams (getOutputStream(), getInputStream(), getErrorStream() ). If not handled, it will block when child process produces output.
Process documentation
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
subprocess may cause the subprocess to block, and even deadlock.
Related
public class Test_Python
{
public static void main( String[] args ) throws IOException
{
String command = "cmd /k start cmd.exe /k \"cd C:\\Workspace\\supply\\environment\\ && setup.bat && python -V ";
Runtime.getRuntime().exec(command);
}
}
When I execute my code, the "python -V" does not work, it is not executed in the cmd window.
But if I delete the "setup.bat" from my command, the "python -V" is executed (I can read the version in the cmd window)
Also, if I manually start a cmd, type setup.bat and then python -V it works.
My batch file is used to set my working environment:
SET basedir=%~dp0
echo %basedir%
cmd /k "cd %basedir%\..\scripts && set PYTHONPATH=%basedir%\..\lib"
Is there any way to know why it fails?
Unlike python Java may need some help. As I can see you are running on Windows.
You invoke the Runtime.exec() method. The method returns a Process instance, and in it's documentation you can read
By default, the created process does not have its own terminal or console. All its standard I/O (i.e. stdin, stdout, stderr) operations will be redirected to the parent process, where they can be accessed via the streams obtained using the methods getOutputStream(), getInputStream(), and getErrorStream(). The parent process uses these streams to feed input to and get output from the process. 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 it is likely your process is started by the OS but gets blocked due to I/O restrictions. Get around that by reading the STDOUT and STDERR streams until your process finishes. One good programming model is visible at https://www.baeldung.com/run-shell-command-in-java
Now that we know the OS is not blocking the process, the issue may be inside the command itself. Note you concatenated several commands using the && operator. I do not have a windows system but searched a bit online:
https://www.ionos.com/digitalguide/server/know-how/windows-cmd-commands/
CommandA && CommandB (the second command is only run if the first was successful)
To check how the first part of your command exits run it separately in Java and do not forget to print the process.exitValue() method.
But looking at the whole picture, all you do with the first part is to change the working directory and set some environment variable. What stops you from running the ProcessBuilder methods? The example in the documentation directly sets the environment and directory.
I want to run linux script from Java program and continue to execute program only when script stop. I am not interested to read script output ... Can anybody help me?
Thanks a lot,
and excuse me for my bad English
Assuming all other threads are idle:
// run the script.
Process proc = Runtime.getRuntime().exec("/path/to/myscript");
// wait for the return code.
int ecode = proc.waitFor();
If you have more complex arguments to your script, or it needs to monitor STDOUT, STDERR, or needs other modifications (like feeding data to STDIN, or changing execution directory, environment variables, etc.) then you should do the same effective procedure, but instead of using Runtime.exec(...) you should build and start the Process manually. Read the Process javadoc and ProcessBuilder javadoc on how to set it up, and start it.
You can also launch the bash interpreter instead
Process proc = Runtime.getRuntime().exec("/bin/bash /path/to/myscript");
int ecode = proc.waitFor();
This may work in some generally broken cases when #rolfl solution may not work (non executable script file, #!/ header missing, etc)
I'm running a Java (.jar) program from a bat script that near the end has the following (on windows)
Runtime.getRuntime().exec("svn co http://myrepository.com/someproj");
Thread.sleep(20000);
It checks out about 1/10th of the directories and 1 file and then it does nothing. I suspect the reason it is pausing on the file but I couldn't find anything. The bat script is run as an administrator.
A common reason for an exec command to block is that it is either waiting for input from the parent process (or the console), or blocked because the parent process is not reading the child processes standard output or error stream.
I have a java project built that I want to run from another java program. But when I call it using the exec command it does not execute immediately but waits for the current program to end. If I add a waitFor statement then the Program hangs as the main program waits for the process and the Process is waiting for the Main program. Does anyone know how I can solve this? Or why it is behaving in such a manner? I need this jar file to execute before a second one can.
Runtime.getRuntime().exec("java -jar \"JavaProject1/dist/JavaProject1.jar\"");
System.out.println("Hello");
p.waitFor();
The location of the jar file is fine and it prints the hello. The main class for the jar file I want to run is in this thread at DaniWeb
Amongst other things, you have to keep reading from the processes STDOUT and STDERR, otherwise it will block.
See, for example, http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
why it is behaving in such a manner?
Because You are creating deadlock in your own program.
When you add waitFor() your program main() in this case waits for the external process to get finished.
It returns Zero when the external process gets fnished normally.
May be the external program has some issues
in a Java application I need to run an external console application. With the window's ones everything is OK:
try {
System.out.println("Running...");
Runtime.getRuntime().exec("notepad.exe");
System.out.println("End.");
}
catch(Exception e) {
System.out.println(e.getMessage());
}
launches notepad successfully.
But if I put D:\\MyProg.exe or .bat or even cmd.exe (which is it PATH as notepad is) it does not work. Without any exeptions. Just:
Running...
End.
First off, most likely Runtime.exec() is returning asynchronously, so just printing "end" will always work, since the exec call returns immediately, which is what you're seeing.
There's a bunch of other problems that could be showing up here. I think what is happening is that the programs you are calling might be outputting I/O on stdout that you are failing to read, or perhaps you need to wait for it to finish before exiting the java process. There's a great article on the various problems with Runtime.exec() you should probably read, it covers this and other problems.
It is because notepad placed in special folder and this folder exists in Path variable.
Run cmd using following line:
Runtime.getRuntime().exec("cmd.exe /c start");
Run other application:
Runtime.getRuntime().exec("cmd.exe /c start C:\\path\\to\\app.exe");