我想使用Runtime.getRuntime().exec
执行一个简单的python脚本Runtime.getRuntime().exec("python test.py")
,该脚本仅包含少量导入,但是由于错误1而失败。我跟踪了该错误,发现没有找到某些库:
Traceback (most recent call last):
File "/Users/firetiti/NetBeans/FiReTiTiLiB/Test.py", line 6, in <module>
from PIL import Image
ImportError: No module named PIL
当我在终端中执行相同的脚本时,一切都很好。因此,我用python python
的绝对路径替换了Runtime.getRuntime().exec("/somewhere/in/my/computer/python3.6 test.py")
,并且它起作用了。
因此Runtime.getRuntime().exec
似乎没有使用python的配置版本。我该如何解决?
如果您使用Java运行exec("python test.py")
,将尝试以与任何其他应用程序相同的方式将python
解析为可执行文件。
假设您使用的是UNIX,Linux或Mac OSX,顺序大致如下:
JVM执行fork
syscall来创建子进程。子进程继承了父(JVM)进程的环境变量。
子进程执行exec syscall,将命令名称,参数和环境变量传递给它。
如果命令名称是简单名称,则系统调用尝试通过在命令搜索路径上的目录中搜索可执行文件来将其解析为路径名;即具有适当执行权限集的一个。
如果找到可执行文件,则根据其签名将其加载到子进程中或解释为脚本。
在您的情况下,第3步无效。具体来说,它在搜索路径中找到错误的python
版本。搜索路径由PATH
环境变量确定,该环境变量继承自父JVM。
因此,如果在交互式shell中和从Java获得不同的结果,则最有可能意味着它们具有不同的PATH
变量。这是要检查的第一件事。例如,在您的Java应用程序中,查看其输出内容:
System.out.println(System.environ().get("PATH"));
并检查它会找到的第一个python
命令是您想要的版本。
可能的解决方案:
PATH
ProcessBuilder
在修改后的环境下执行外部命令python
命令使用绝对路径名。python2
或python3
。 (典型的Linux软件包等将从python2
和python3
链接到正确的可执行文件。)