How to fix the below error in java?
Requirement: Running python program using java
supporting lib:jython-standalone-2.7.0.jar
python installed: python 3.6.0
public static void main(String[] args) throws FileNotFoundException, ScriptException, IOException {
System.out.println("Hello world!!");
//option 1
StringWriter writer = new StringWriter(); //ouput will be stored here
ScriptEngineManager manager = new ScriptEngineManager();
ScriptContext context = new SimpleScriptContext();
context.setWriter(writer); //configures output redirection
ScriptEngine engine = manager.getEngineByName("python");
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("import sys\nsys.path.append('C:\\Users\\johns\\AppData\\Local\\Programs\\python\\python36\\Lib\\site-packages')");
engine.eval(new FileReader("C:\\Users\\johns\\Desktop\\python\\pytest.py"), context);
System.out.println("");
System.out.println(writer.toString());
//option 2
// String execCmd = execCmd("python
C:\\Users\\johns\\Desktop\\python\\pytest.py");
// System.out.println("From Cmd Prompt" + execCmd);
}
public static String execCmd(String cmd) throws java.io.IOException {
Process proc = Runtime.getRuntime().exec(cmd);
java.io.InputStream is = proc.getInputStream();
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
String val = "";
if (s.hasNext()) {
val = s.next();
} else {
val = "";
}
return val;
}
Error Message:
Exception in thread "main" javax.script.ScriptException: AttributeError: 'tuple' object has no attribute 'major' in <script> at line number 1
at org.python.jsr223.PyScriptEngine.scriptException(PyScriptEngine.java:202)
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:42)
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:47)
at pythonproj.PythonProj.main(PythonProj.java:47)
Caused by: Traceback (most recent call last):
File "<script>", line 1, in <module>
File "C:\Users\johns\AppData\Local\Programs\python\python36\Lib\site-
packages\pytesseract\__init__.py", line 1, in <module>
from .pytesseract import (
File "C:\Users\johns\AppData\Local\Programs\python\python36\Lib\site-
packages\pytesseract\pytesseract.py", line 10, in <module>
from PIL import Image
File "C:\Users\johns\AppData\Local\Programs\python\python36\Lib\site-
packages\PIL\Image.py", line 31, in <module>
from ._util import py3
File "C:\Users\johns\AppData\Local\Programs\python\python36\Lib\site-
packages\PIL\_util.py", line 3, in <module>
py3 = sys.version_info.major >= 3
AttributeError: 'tuple' object has no attribute 'major'
at org.python.core.Py.AttributeError(Py.java:205)
at org.python.core.PyObject.noAttributeError(PyObject.java:1013)
at org.python.core.PyObject.__getattr__(PyObject.java:1008)
Advice which is preferable approach to run the python program with jython or by calling command process as option 2 in above code
2 Answers 2
It seems the exception you are getting is caused by a jython bug (that is apparently fixed with jython-2.7.1).
Regarding your other question; if all you want to do is run the script and not interact with the interpreter in any way, and you know a suitable python version is installed on the system, using a process would probably be a lot easier and avoid this and potential other problems with jython.
Comments
Since jython project is inactive and not python 3 so not up-to-date (see comments), your option2 to launch python.exe as a system executable is the good one.
It can't work the way you coded it because Runtime.exec doesn't execute a DOS Cli but directly an executable. So what you launch is python.exe, and your py file is an argument of this command
Here is an approach for launching it
public static String execPython(String pythonFile) throws java.io.IOException {
// modification here: provide a String array with "python" as first argument,
// you may add other argument of your python program
Process proc = Runtime.getRuntime().exec(new String[] {"python",pythonFile});
java.io.InputStream is = proc.getInputStream();
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
String val = "";
if (s.hasNext()) {
val = s.next();
} else {
val = "";
}
return val;
}
public static void main(String[] args) {
try {
String stdStream = execPython("C:\\Users\\johns\\Desktop\\python\\pytest.py");
System.out.println(stdStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
5 Comments
Runtime.exec(String) doesn't run CMD (unless you explicitly tell it to) but it does split the string at whitespace and take the first token as the programname (searched in the same fashion as CMD) which for this particular case is sufficient.