解决Linux环境使用Java调用Python脚本的问题
- 整体描述
- 基本操作
- 1. 基本命令
- 2. 执行结果
- 3. 查看运行错误信息
- 4. 简单示例
- 问题汇总
- 1. 安装Python环境
- 2. 缺少Python库
- 3. 运行时报错
整体描述
做一个项目,需要使用java调用Python脚本,从开始各种错误到最后调用成功,记录一下:
基本操作
1. 基本命令
首先在Linux系统下,使用Java调用Python脚本,传入参数,需要使用Runtime.exec()方法,即在java中使用shell命令,这个方法有两种使用形式:
- 无参数传入,直接执行Linux相关命令:Process pr = Runtime.getRuntime().exec(String cmd);
- 有参数传入,并执行Linux命令:Process pr = Runtime.getRuntime().exec(String[] cmd);
无参数可以直接传入字符串,如果需要传参数,就要用2的字符串数组实现。
2. 执行结果
使用exec方法执行命令,如果需要执行的结果,用如下方式得到:
String line;
while ((line = input.readLine()) != null) {
System.out.println(line);
if ("".equals(line)) {
break;
}
}
System.out.println("line------------------>" + line);
3. 查看运行错误信息
可以用以下方式查看运行的错误信息:
BufferedReader errorResultReader = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
String errorLine;
while ((errorLine = shellErrorResultReader.readLine()) != null) {
System.out.println("errorStream:" + errorLine);
}
int exitCode = pr.waitFor();
System.out.println("exitCode:" + exitCode);
4. 简单示例
当然exec还有很多本文未说明的方法,本文目前只需要以上几个方法进行定位,尤其是3。
举一个简单的例子,使用Java调用Linux的pwd命令,得到当前所在目录:
String result = "";
String cmd = "pwd";
Process pr = Runtime.getRuntime().exec(cmd);
InputStreamReader ir = new InputStreamReader(pr.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
result = input.readLine();
System.out.println("result:" + result);
问题汇总
1. 安装Python环境
运行Python会需要Python环境,和很多Python的库,如果没有就会报错。首先安装Python环境,我安装的是Python3.8,这个有很多教程,就不具体说了。就是下载对应版本的安装包,上传到服务器,进行安装。输入:
python -V
能够正常显示出当前python的版本号,就是安装成功了。
2. 缺少Python库
折腾完Python环境,再次运行Python脚本,发现还报错,可以用上文中查看错误信息的方法看到Java调用时的错误信息,提示缺少XXX库,这个错误提示就非常明确了,安装就完了,不过安装过程也非常曲折,我的是缺少dlib库,就是和人脸相关的,这个网上也有很多教程,我的安装过程是:首先安装了miniconda,然后用conda安装cmake和boost,然后安装dlib就成功了。
3. 运行时报错
Python安装完,各种库也安装完了,而且在Linux直接调用Python脚本已经运行成功,这时候正常应该没什么问题了,直接使用Java代码调用就可以了,使用如下代码:
String result = "";
String[] cmd = {"python", "/home/test.py"};
Process pr = Runtime.getRuntime().exec(cmd);
InputStreamReader ir = new InputStreamReader(pr.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
result = input.readLine();
System.out.println("result:" + result);
依旧报错,找不到库,不应该啊,我在Linux环境直接用shell窗口都可以运行了,说明Linux下的环境和脚本应该都没有问题,还是Java调用的问题。经过我不断尝试和百度,发现了如下解决方案:
在Java调用Python时,需要指定Python的目录,使用如下命令:
which python
查看python使用的路径,然后在Java调用的时候写出绝对路径:
String[] cmd = {"/root/miniconda3/bin/python", "/home/test.py"};
到此问题解决。