Failed to run Python script from Java using Intellij - java

I'm attempting to run a Python script using Java code in Intellij IDEA:
String commandString = "python /home/.../mypythonscript.py arg1 arg2";
try {
Process process = Runtime.getRuntime().exec(commandString);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
} catch(IOException e) {
System.out.println(e.getMessage());
The Python script outputs a single String, and works great when I run it from my Ubuntu Linux terminal. However, using the above Java to run the Python script returns an error message:
Failed to run Python Script: Cannot run program "python": error=2, No such file or directory.
The file path is correct (the path and arguments I give are identical to what I used to run the Python script in the terminal), and I've set the script permissions to 777. In Intellij, I've also gone to File>Settings>Appearance & Behavior>Path Variables and added a path to the folder that contains the Python script (it's being held in a folder for Pycharm projects). However, I'm still getting the error.
Any help would be much appreciated!

A more experienced Java developer friend of mine who doesn't have an account figured out the problem, the solution to which I'm posting here for anyone encountering a similar issue in the future:
The script was written in Python3, but the code I used:
String commandString = "python /home/.../mypythonscript.py arg1 arg2";
is for Python 2. It should have been written:
String commandString = "python3 /home/.../mypythonscript.py arg1 arg2";

Related

When using jar package, Runtime.getRuntime().exec does not work to get bash_profile environment variable

I am using intellij IDEA to develop an AndroidStudio Plugin. The function of the plugin is to create a flutter plugin.
I have written a shell script, which uses flutter create to create a flutter plugin. Then I wrote the code to call the script in intellij IDEA, and everything worked here. What I mean is that using Runtime.getRuntime().exec can call shell scripts normally, and it can also meet my expectations.
public static class ShellUtil {
public static String runShell(String shStr) throws Exception {
Process process;
String[] command = new String[] {"bash","-c",shStr};
process = Runtime.getRuntime().exec(command);
process.waitFor();
BufferedReader read = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
String result = "";
while ((line = read.readLine())!=null){
result+=line;
}
return result;
}
}
But after I compiled it into a jar package and installed it in AndroidStudio, everything changed. The PATH I printed out was only /usr/bin:/bin:/usr/sbin:/sbin, I can be sure that I added flutter to the PATH of bash_profile. I searched a lot of information, and it seems to be saying that java has opened a new shell process, and this process cannot get all the environment variables of bash_profile.
My question is: How can I get the environment variables in bash_profile in the java shell process?
Latest development: I execute source ~/.bash_profile at the beginning of the shell file, and I can get the environment variables I want. But it does not mean that my PATH is not effective. Before adding, I restarted the computer and run intellij IDEA to ensure that the environment variables in bash_profile are all effective.
Although I can execute export PATH before executing the script in java, this is not what I want, because the path for installing flutter is different for everyone, and I hope to get the result of which flutter.

Execute a shell script (shell script which uses perl and other shell scripts) in Linux from java

I am trying to execute a shell script (that makes use of a perl script and other shell scripts) from java program, however I am not successful, here is what I tried:
On the Linux server, in a folder test1/testJava the following scripts are available:
decode24.sh (the main script I call from java program, this script makes use of the other scripts listed below)
fram.sh
shadow.pl
light.sh
Here is what I try from java:
try {
ConnBean cb = new ConnBean("xx.yyy.zz.p", "user","passme");
ssh = SSHExec.getInstance(cb);
CustomTask ct1 = new ExecShellScript("/test1/testJava", "./decode24.sh", "arg1");
ssh.connect();
net.neoremind.sshxcute.core.Result res = ssh.exec(ct1);
}catch......
Result after execution:
error message:
./decode.sh[17]: shadow.pl: not found [No such file or directory]
./decode.sh[21]: fram.sh: not found [No such file or directory]
The error comes from your decode.sh script. It cannot find the shadow.pl and fram.sh scripts that it executes. Probably because the CWD or path is not set to the script dir when you run the script.
The most robust way to solve it is to change your decode.sh script to use absolute paths to the shadow.pl and fram.sh scripts. That way you can execute decode.sh from any directory.
If you use bash, check out this question for a neat way to resolve the absolute directory to the scripts to avoid hard coding the path.
Let decode.sh find out the directory it is in (see bash solution) and use the path for calling the others.

Windows can't run python script from within eclipse

I'm on a Windows machine and using Eclipse.
My java code is invoking a python script by using :
Process p = Runtime.getRuntime().exec("cmd /c e:\\dev\\CodeBase\\WebService\\src\\com\\rest\\service\\PythonScript.py");
On running the code it opens the prompt for choosing a program to run the script with. What can I do to make it run implicitly?
Try running Python interpreter instead:
Process p = Runtime.getRuntime().exec("[PATH TO YOUR PYTHON DIR]\\python.exe e:\\dev\\CodeBase\\WebService\\src\\com\\rest\\service\\PythonScript.py");
Usually [PATH TO YOUR PYTHON DIR] is something like C:\\Python27\\ or C:\\Python34 depending on your Python version.
If you have Python directory added to your system PATH variable sole .exec("python ...") will suffice.
You will need to convert the .py file to .exe use Py2Exe. You can download it and follow the instructions to convert it.

Ruby script that sets environment variable fails with Invalid argument - ruby_setenv (Errno::EINVAL) when started from a Java process on Windows

I have a very simple ruby script that looks like this:
puts "Running test program"
ENV["TEST"] = "foo"
puts ENV["TEST"]
When I run this script from the command line it works as expected:
C:\Temp\rb-test>ruby foo.rb
Running test program
foo
What I need to do is to launch this script from a Java program. The Java program looks like this:
Path path = FileSystems.getDefault().getPath("c:", "temp", "rb-test");
ProcessBuilder pb = new ProcessBuilder("ruby.exe", "foo.rb").directory(path.toFile()).redirectErrorStream(true);
Process process = pb.start();
process.waitFor();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = bufferedReader.readLine();
while (line != null) {
System.out.println(line);
line = bufferedReader.readLine();
}
When I run the Java program from Eclipse I get the following output:
foo.rb:2:in `[]=': Invalid argument - ruby_setenv (Errno::EINVAL)
from foo.rb:2:in `<main>'
Running test program
In reality I am calling a larger Ruby script from a third party product (Vagrant), why changing the Ruby script is not an option.
Why is this happening? Can I get around it by modifying my Java code somehow?
Ruby version: ruby 1.9.3p0 (2011-10-30) [i386-mingw32]
Update: The java code actually works if I run it from a cmd window. It does not work when I run it from within Eclipse. Unfortunately this does not help much since I am working on a tool we will run from within Eclipse.
Update 2: If I start a cmd window from Eclipse, I get the same problem when I run the ruby script from within this cmd window. This leads me to believe there is some kind of permission issue. However, I cannot see any permission differences between the cmd I start through the start menu and the one started through Eclipse. Both are run as the same user and all security properties I can see for the process are identical.
Update 3: Tried the latest version of Ruby (2.0.0p247 (2013-06-27) [i386-mingw32]). Same behavior.
The problem was that when I started the Ruby script from Eclipse I had a different environment. Specifically, I had a CLASSPATH environment variable that looked really strange. I think the cause of this is the size of the CLASSPATH variable. It is really really long before being passed on to my sub process but within the sub process it is truncated and looks broken.
I am suspecting I am running into problems with the max size of the Windows environment block (see details here: http://blogs.msdn.com/b/oldnewthing/archive/2010/02/03/9957320.aspx). I will not investigate this further but have fixed my code to remove the CLASSPATH variable before starting the process.
Path path = FileSystems.getDefault().getPath("c:", "temp", "rb-test");
ProcessBuilder pb = new ProcessBuilder("ruby.exe","foo.rb").directory(path.toFile()).redirectErrorStream(true);
pb.environment().remove("CLASSPATH");
Process process = pb.start();
process.waitFor();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = bufferedReader.readLine();
while (line != null) {
System.out.println(line);
line = bufferedReader.readLine();
}
Had a similar issue running vagrant as part of this Wocker installation:
http://wckr.github.io/
The problem was my system environment PATH was too long. I trimmed out a load of cruft from it and vagrant (based on ruby) runs up fine.

Process not found when running from getRuntime.exec() from the JVM

I am trying to run the following code from within Eclipse:
Process process = Runtime.getRuntime().exec("gs");
However I get the exception:
java.io.IOException: Cannot run
program "gs": error=2, No such file or
directory
Running gs from the command prompt (OS X) works fine from any directory as it is on my PATH. It seems eclipse doesn't know about my path environment variable, even though I have gone into run configurations and selected PATH on the environment tab.
In additional effort to debug this issue I tried the following code:
Process process = Runtime.getRuntime().exec("echo $PATH");
InputStream fromStdout = process.getInputStream();
byte[] byteArray = IOUtils.toByteArray(fromStdout);
System.out.println(new String(byteArray));
The output was $PATH, hmm. Can someone nudge me in the correct direction?
you are assuming that exec() uses a shell to execute your commands (echo $PATH is a shell command); for the sake of simplicity you can use System.getenv() to see your $PATH:
System.out.println(System.getenv("PATH"));
EDIT
Often a better and flexible alternative to Runtime.exec() is the ProcessBuilder class.
I had the same issue and i found the problem. The Path Variable in Eclipse had different content than the one from the command Line.
Solution:
Look up for the $Path variable in command Line and copy the content. Then open Run Configuration->Environment and select new. Name: $PATH Value: insert the copied content.
That solved the Problem.

Categories

Resources