[JAVA]Runtime 调用Python脚本(可传参)

本文介绍如何在Java中通过Runtime调用Python脚本来查询Oracle数据库并处理数据。主要涉及环境变量设置、Python脚本编写及Java调用流程,解决Python调用Oracle驱动和Java执行Python脚本时的环境变量问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用场景:在java中通过runtime调用python脚本

1.python脚本中连接Oracle数据库查询数据后输出文件,脚本头内容如下

#!/usr/bin/python3
#encoding=utf-8
import os
from pypinyin import pinyin,lazy_pinyin
import cx_Oracle as oracle
import sys
import pypinyin
import datetime
import redis
import argparse

os.environ["ORACLE_HOME"] = '/Users/apple/Library/Oracle/instantclient_12_2'
os.environ["DYLD_LIBRARY_PATH"] = '/Users/apple/Library/Oracle/instantclient_12_2'
os.environ["LD_LIBRARY_PATH"] = '/Users/apple/Library/Oracle/instantclient_12_2'
os.environ["NLS_LANG"] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
#定义脚本说明文案
parser = argparse.ArgumentParser(description='-updateuser:操作用户名')
#定义脚本入参
parser.add_argument('-uu', type=str,default=None)

脚本下面的内容都是查询数据库,然后将查询结果输出为文件,就略过了。再补充一下main方法的内容

if __name__ == '__main__':
    args = parser.parse_args()
    print(args.uu)
    cc = ChineseConvertPinYin()
    cc.execute(args.uu)

2.Java中通过Runtime调用执行python

//设置java执行进程的环境变量(临时的)

String[] envp = new String[]{"LD_LIBRARY_PATH=/Users/apple/Library/Oracle/instantclient_12_2","LANG=UTF-8"};

//exec方法 第一个参数是执行的命令,第二个参数为环境变量数据(环境变量设置方式:NAME=VALUE)

Process pr=Runtime.getRuntime().exec("python3 /Work/pythonWork/pinyin/ChineseConvertPinYin.py -uu wzj",envp);

System.out.println(pr.waitFor());//返回0表示执行成功,返回1表示执行失败(PS:网上看到有数如果执行多条命令的时候,这个waitFor必不可少,本次没有实际用途,暂未深入研究)

//获取输出流,即:python脚本中的print 或 shell 的echo

BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));

String line = null;

while((line = in.readLine()) != null){

System.out.println(line);//输出每一行打印或echo

}

//获取异常输出流

BufferedReader ine = new BufferedReader(new InputStreamReader(pr.getErrorStream()));

String linee = null;

while((linee = ine.readLine()) != null){

System.out.println(linee);

}

3.总结 

过程中遇到过两个问题:

1.Python调用Oracle连接驱动的问题,使用pip安装cx_Oracle后,总是报错,大致内容如下:

cx_Oracle.DatabaseError: DPI-1047: 64-bit Oracle Client library cannot be loaded: "dlopen(libclntsh.dylib, 1): image not found". See https://oracle.github.io/odpi/doc/installation.html#macos for help

解决方式:安装oracle连接驱动,此处参考 http://jashawn.iteye.com/blog/1654441

2.Java Runtime执行的时候,Python脚本中的临时环境变量未生效(此处有待后续研究),遂在java进程中设置独立环境变量,代码如下:

String[] envp = new String[]{"LD_LIBRARY_PATH=/Users/apple/Library/Oracle/instantclient_12_2","LANG=UTF-8"}; 

3.补充一下,linux or mac下安装oracle驱动包以及环境变量配置(以下代码来源网络)

3.1下载所需要的驱动包

wget https://github.com/bumpx/oracle-instantclient/raw/master/instantclient-basic-linux.x64-11.2.0.4.0.zip -O /tmp/instantclient-basic-linux.x64-11.2.0.4.0.zip && \

wget https://github.com/bumpx/oracle-instantclient/raw/master/instantclient-sdk-linux.x64-11.2.0.4.0.zip -O /tmp/instantclient-sdk-linux.x64-11.2.0.4.0.zip 

3.2解压到指定目录

unzip /tmp/instantclient-basic-linux.x64-11.2.0.4.0.zip -d /usr/local/ && \

unzip /tmp/instantclient-sdk-linux.x64-11.2.0.4.0.zip -d /usr/local/

3.3建立软连

ln -s /usr/local/instantclient_11_2 /usr/local/instantclient && \

ln -s /usr/local/instantclient/libclntsh.so.11.1 /usr/local/instantclient/libclntsh.so

3.4配置环境变量

echo "LD_LIBRARY_PATH=/usr/local/instantclient:$LD_LIBRARY_PATH" >> .bash_profile

echo "PATH=$PATH:/usr/local/instantclient" >> .bash_profile

echo "export LD_LIBRARY_PATH PATH" >> .bash_profile

3.5使环境变量生效

source .bash_profile 

Java中,你可以使用`Runtime.getRuntime().exec()`方法来执行Python脚本,并通过标准输入和输出来与之交互。如果你想要调用Python脚本中的特定函数,首先你需要编写Python脚本,该脚本应该包含一个可以接收命令行数并执行相应操作的函数。 以下是一个简单的步骤示例: 1. **创建Python脚本**: Python脚本文件(例如`script.py`): ```python def run_function(param): print(f"Running function with parameter: {param}") ``` 2. **Java代码部分**: 使用`Runtime.exec`执行Python脚本并传递数给指定函数: ```java import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception { String pythonScript = "script.py"; // Python脚本路径 String functionName = "run_function"; // 要调用的函数名 String functionParam = "example_param"; // 函数数 Process process = Runtime.getRuntime().exec("python " + pythonScript); Scanner scanner = new Scanner(process.getInputStream()); try { // 假设你的Python函数返回结果是打印在控制台的 String output = scanner.nextLine(); System.out.println("Python Function Output: " + output); // 如果你想直接调用函数而不是获取输出,可以用以下方式(这依赖于你的脚本结构) // process.getOutputStream().write((functionName + "(" + functionParam + ")").getBytes()); // process.getOutputStream().flush(); } finally { scanner.close(); } } } ``` 请注意,上述代码假定Python脚本能从命令行接受数并在控制台上输出。如果函数需要更复杂的交互,可能需要处理进程的标准输入和错误流(process.getErrorStream())以及使用其他机制,如序列化数据或网络通信。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值