I have tried running a shell script from a Java program, but the entire script is not being executed. And idea why we might come across such problem?
The Java code to execute shell script:
File file = new File("/path/to/script");
String COMMAND= "./run";
ProcessBuilder p = new ProcessBuilder(COMMAND);
p.directory(file);
try {
Process startProcess= p.start();
} catch (IOException e) {
e.printStackTrace();
}
The script runs fine but not whole script is executed. It seems like only the 1st line is being executed.
If you are sure that the script starts running the problem is not in java but in script itself.
The reason of difference may be the wrong path or wrong environments. When you are running script from console you are in your user's environment, so script can use all environment variables.
Try to add some debug outputs to figure the problem out.
Related
I'm trying to run a Python script from a Java program using Process and ProcessBuilder, however Java keeps using the wrong version of Python. (The script needs 3.6.3 to run and Java runs Python 2.7)
However when I run the script from the terminal (outside of Java), it runs the correct Python (3.6.3). How does one change what version of Python gets run when called by Java?
The short version is it changes with your PATH environment variable.
Under Windows, Technet has the answer. Scroll down to the 'Command Search Sequence' section. This answer explains it nicely.
For UNIX-like OS's, this answer is nicely detailed.
There are two very useful commands for determining which executable is going to be called: which for UNIX-likes and where for newer Windows.
The most likely reason for the difference between Java and the terminal is a difference in your PATH. Perhaps your Java version is being run with a modified PATH? A launch script of some kind may be changing it.
Add /usr/bin/python3.4 to the start of your command to force the version of python you want. If you're not sure where python is installed, have a go at using whereis python and seeing what you get back.
private int executeScript(final List<String> command) {
try {
final ProcessBuilder processBuilder = new ProcessBuilder("/usr/bin/python3.4").command(command);
processBuilder.redirectErrorStream(true);
System.out.println("executing: " + processBuilder.command().toString());
final Process process = processBuilder.start();
final InputStream inputStream = process.getInputStream();
final InputStream errorStream = process.getErrorStream();
readStream(inputStream);
readStream(errorStream);
return process.waitFor();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return -1;
}
Then just pass in the List containing your python commands.
I have done quite a bit of research on this, and unfortunately have been unable to find an answer that is suitable to the problem I'm currently having.
My question isn't as simple as "how do I run a python script from Java," to which there exists at least 10 threads all containing the same answer. I understand how to do that. My problem is as follows:
I have a .py file (gui.py) which looks something like this:
#!/usr/bin/env python
import matplotlib.pyplot as plt
import copy
import math
import numpy as np
class GUI(object):
...
...
...
if __name__ == '__main__':
GUI.run()
This gui is an interactive matplotlib plot on which users draw stuff. Details aren't important - bottom line is the script runs for as long as the matplotlib window is open.
Now, I'm building a Java app on the side, and there's a button which when clicked creates a Java Process object which will call the script. I know from reading other posts that PIPE cannot be called from the java runtime, so I've created a .sh file which wraps around this python script.
shell.sh:
#!/bin/sh
python /mypath/to/the/gui.py
The Java to call the shell script:
view.getLaunchGuiButton().addActionListener((e) -> {
try {
String[] prcArgs = new String[] { "/mypath/to/shell.sh" };
Process proc = Runtime.getRuntime().exec(prcArgs);
} catch (IOException e1 ) {
e1.printStackTrace();
}
});
The shell script is correct - when I run it from the terminal correctly everything functions as normal.
I know that the Java is indeed executing the shell script, and calling the python script. There are no errors. I didn't set up any BufferedReader because there's nothing to read - I just need to GUI to open. I believe that the problem is that once the shell is executed, the "terminal" so-to-speak which is opened by the Runtime is immediately closed, hence it kills the python script and therefore the GUI.
My question is, how do I keep the Runtime from simply running and immediately killing the python script (AKA closing the terminal)?
Things I've already done:
chmod +x ../../shell.sh
Tried using nohup /call/python/here & in the shell script. Didn't work.
Tried using Java's ProcessBuilder instead of the Runtime. No difference.
Any ideas? Thank you all in advance.
From the Java Button listner I exec-ed xterm:
try {
Process p = Runtime.getRuntime().exec("xterm");
Thread.sleep(1500);
} catch (IOException e1 ) {
e1.printStackTrace();
}
In ~/.bashrc I added my command which starts my Python script with GUI:
if [[ -z "$XTERM_ONCE" ]]
then
export XTERM_ONCE=$(date)
cd /home/qswadey/path/to/py/script/
python3 pyscript_with_GUI.py
fi
The Python GUI shows up and continues...
The idea of running a command on xterm startup, for all xterm is sourced from this thread: How to run a command on the startup of an xterm?
The Thread.sleep is just for holding the xterm for some time to see output of short command, however the xterm remains running in interactive mode
I have this code that is supposed to run a executable jar, but whenever the code is executed nothing happens?
try {
proc = Runtime.getRuntime().exec("java -jar C://X-Dock//MP3Player.jar");
} catch (IOException e1) {
e1.printStackTrace();
}
The JAR works fine if I run it manually, but that line of code just doesn't work. And I know for sure that the code is called.
If you has a JRE after version 5, java provides a process builder. So, try something like this:
final ProcessBuilder pBuilder = new ProcessBuilder("/java/path", "-jar", "your_jar.jar");
pBuilder.directory(new File("your/working/directory"));
final Process process = pBuilder.start();
"/java/path" is path for java installation, can be replaced by java, if java is in the environment variables.
See more at ProcessBuilder.
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.
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");