Have you looked at these? They suggest different ways of doing this:
Call Python code from Java by passing parameters and results
How to call a python method from a java class?
In short one solution could be:
public void runPython()
{ //need to call myscript.py and also pass arg1 as its arguments.
//and also myscript.py path is in C:\Demo\myscript.py
String[] cmd = {
"python",
"C:/Demo/myscript.py",
this.arg1,
};
Runtime.getRuntime().exec(cmd);
}
edit: just make sure you change the variable name from str to something else, as noted by cdarke
Your python code (change str to something else, e.g. arg and specify a path for file):
def returnvalue(arg) :
if arg == "hi" :
return "yes"
return "no"
print("calling python function with parameters:")
print(sys.argv[1])
arg = sys.argv[1]
res = returnvalue(arg)
print(res)
with open("C:/path/to/where/you/want/file.txt", 'w') as target: # specify path or else it will be created where you run your java code
target.write(res)
Answer from mkaran on Stack OverflowHave you looked at these? They suggest different ways of doing this:
Call Python code from Java by passing parameters and results
How to call a python method from a java class?
In short one solution could be:
public void runPython()
{ //need to call myscript.py and also pass arg1 as its arguments.
//and also myscript.py path is in C:\Demo\myscript.py
String[] cmd = {
"python",
"C:/Demo/myscript.py",
this.arg1,
};
Runtime.getRuntime().exec(cmd);
}
edit: just make sure you change the variable name from str to something else, as noted by cdarke
Your python code (change str to something else, e.g. arg and specify a path for file):
def returnvalue(arg) :
if arg == "hi" :
return "yes"
return "no"
print("calling python function with parameters:")
print(sys.argv[1])
arg = sys.argv[1]
res = returnvalue(arg)
print(res)
with open("C:/path/to/where/you/want/file.txt", 'w') as target: # specify path or else it will be created where you run your java code
target.write(res)
calling python from java with Argument and print python output in java console can be done with below simple method:
String pathPython = "pathtopython\\script.py";
String [] cmd = new String[3];
cmd[0] = "python";
cmd[1] = pathPython;
cmd[2] = arg1;
Runtime r = Runtime.getRuntime();
Process p = r.exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((s = in.readLine()) != null){
System.out.println(s);
}
Command line arguments are not stdin. args[0] is a command line argument. You should be able to do it like
cmd = ['java', java_class, 'SomeInputString']
For your requirement (execute a java file passing a single argument from Python and after execution, return the result back to the script that called it), Popen is not reccomended. This is because it is non-blocking. The code does not wait for the output to be returned. Please use the subprocess.run() command for Python > 3.7.
result = subprocess.run(
['java', '-cp', EXTERNAL_JAR_PATHS, 'MyJavaCode.java', ARGUMENT],
capture_output = True,
text = True,
cwd = PATH_TO_CODE
)
result.stdout gives the program output and result.stderr gives information on errors if any.
Why this is better than debugging the Popen code:
- Simpler and apt for your requirement. No need to deal with streams, deadlock issues etc
- subprocess.run is the default approach reccomended for > 3.7 python version
- Popen creates a new process and additional logic to ensure that the new process is terminated correctly etc need to be considered
Having said that in your case the immediate issue/error is correctly solved by Elliot. My approach addresses the larger requirement outlined in your last paragraph
Last argument in your below call is for command line arguments:
PythonInterpreter.initialize(System.getProperties(), System.getProperties(), new String[0]);
From PythronInterpreter javadocs:
initialize
public static void initialize(Properties preProperties, Properties postProperties, String[] argv)
Initializes the Jython runtime. This should only be called once, before any other Python objects (including PythonInterpreter) are created. Parameters: preProperties - A set of properties. Typically System.getProperties() is used. preProperties override properties from the registry file. postProperties - Another set of properties. Values like python.home, python.path and all other values from the registry files can be added to this property set. postProperties override system properties and registry properties. argv - Command line arguments, assigned to sys.argv.
I had the same issue and found it could be resolved by using "interned" string, i.e.,
for (int i = 0; i args.length; ++i) {
args[i] = args[i].intern();
}
I am using Jython 2.5.3. Hope this will help.