Java调用Python

今天遇到Java调用一个Python脚本的问题,纠结了大半天,遇到各种问题。网上搜索的大部分都是用jython,但是我想要调用的python脚本里有import urllib,这个urllib也不是什么第三方扩展库,在python的安装path下的Lib下就有,在python命令行下肯定是能找到的。但是用jython的话,sys的path里面就太少了。示例代码:

import org.python.core.Py;
import org.python.core.PySystemState;
import org.python.util.PythonInterpreter;

public class Test3 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        
        PythonInterpreter interpreter = new PythonInterpreter();  
        
        PySystemState sys = Py.getSystemState(); 
        //sys.path.add("D:\\jython2.5.2\\Lib");
        System.out.println(sys.path.toString()); 
        
        interpreter.exec("print 'hello'");  
        
        interpreter.exec("import sys");
        interpreter.exec("print sys.path");
        
//        interpreter.exec("import urllib");
//        interpreter.exec("print urllib");
    }

}

 打印出来的sys.path为:

['D:\\eclipse_jee_workspace\\ZLabTest\\lib\\Lib', '__classpath__', '__pyclasspath__/']

 这儿就只有eclipse的工程的路径包含了,所以当然找不到urllib啦。而在命令行下打印sys.path为:


用jython差的lib库少太多了,
也懒得用类似sys.path.add("D:\\jython2.5.2\\Lib");一个一个加了,所以果断放弃jython。

 

 

然后查到可以用Runtime.getRuntime().exec("python test.py");示例代码如下:

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Test5 {
        public static void main(String[] args){
                try{
                        System.out.println("start");
                        Process pr = Runtime.getRuntime().exec("python test.py");
                        
                        BufferedReader in = new BufferedReader(new
                                InputStreamReader(pr.getInputStream()));
                        String line;
                        while ((line = in.readLine()) != null) {
                            System.out.println(line);
                        }
                        in.close();
                        pr.waitFor();
                        System.out.println("end");
                } catch (Exception e){
                            e.printStackTrace();
                        }
                }
}

 test.py的文件内容为:

import sys
import urllib
print "hello"
print sys.path

 java程序运行的结果为:

start
hello
['D:\\eclipse_jee_workspace\\ZLabTest', 'C:\\Windows\\system32\\python27.zip', 'D:\\Python27\\DLLs', 'D:\\Python27\\lib', 'D:\\Python27\\lib\\plat-win', 'D:\\Python27\\lib\\lib-tk', 'D:\\Python27', 'D:\\Python27\\lib\\site-packages']
end

 这就比较对了。但是中途还是遇到了很多问题,在Eclipse中运行上面的java程序抛出异常:

java.io.IOException: Cannot run program "python": CreateProcess error=2, ϵͳÕҲ»µ½ָ¶

at java.lang.ProcessBuilder.start(ProcessBuilder.java:460)

at java.lang.Runtime.exec(Runtime.java:593)

at java.lang.Runtime.exec(Runtime.java:431)

at java.lang.Runtime.exec(Runtime.java:328)

at com.mysrc.Test5.main(Test5.java:10)

Caused by: java.io.IOException: CreateProcess error=2, ϵͳÕҲ»µ½ָ¶

at java.lang.ProcessImpl.create(Native Method)

at java.lang.ProcessImpl.<init>(ProcessImpl.java:81)

at java.lang.ProcessImpl.start(ProcessImpl.java:30)

at java.lang.ProcessBuilder.start(ProcessBuilder.java:453)

... 4 more

就是没法调用python程序,而如果是在命令行下用javac编译,然后java执行的话肯定是对的。怎么才能在Eclipse里也能正常运行了,网上查了半天,在run configurations->environment新建一个PATH,值设为安装的python的路径,再运行就OK了。

 

<think>好的,用户想了解如何在Java调用Python脚本或函数,特别是通过subprocess或JEP库的示例代码。首先,我需要回忆相关的Java调用Python的方法。常见的有使用Runtime执行命令行、ProcessBuilder、Jython、JEP等。用户提到了subprocess和JEP,所以重点在这两个方法。 首先,subprocess应该是Java的ProcessBuilder或Runtime.exec来启动Python进程。这里需要给出示例代码,展示如何执行Python脚本并获取输出。注意异常处理和流的读取,避免阻塞。 然后是JEP,这是一个允许在Java中嵌入Python解释器的库。需要说明如何配置JEP的依赖,比如Maven或Gradle,然后编写调用Python函数的示例代码。要强调JEP的性能优势,特别是在需要频繁调用的场景下。 另外,用户提供的引用中有提到JPype,但用户问题里没有明确提到,是否需要简要比较一下?不过用户明确问了subprocess和JEP,所以可能不需要深入其他方法,但可以稍微提一下其他选项作为扩展。 需要检查引用中的信息是否相关。引用1提到了JPype,但用户可能更关注JEP和subprocess,所以引用可以作为补充说明其他方法存在,但主要回答用户提到的两个方法。引用2是关于JDBC漏洞利用的文件,似乎不相关,可能不需要引用。 接下来,按照用户的结构要求,回答需要分点,结构清晰,使用中文,行内公式用$...$,独立公式单独成段。不过用户的问题不涉及数学公式,所以可能不需要使用。但需要生成相关问题。 最后,确保示例代码正确,语法高亮,并解释每个步骤。注意subprocess方法中的输入输出流处理,避免死锁。同时,JEP的示例需要展示如何传递参数和获取返回值。 总结步骤:先介绍subprocess方法,给出代码示例和注意事项;然后介绍JEP方法,配置依赖和示例代码;最后比较两种方法的优缺点,适用场景。生成相关问题时要围绕Java调用Python的其他方法、异常处理、性能优化等。</think>### Java调用Python脚本或函数的方法教程 #### 1. 使用 `ProcessBuilder`(命令行调用) 通过Java启动子进程执行Python脚本,适用于简单脚本调用。 ```java import java.io.BufferedReader; import java.io.InputStreamReader; public class PythonSubprocess { public static void main(String[] args) { try { ProcessBuilder pb = new ProcessBuilder("python", "script.py", "arg1", "arg2"); Process process = pb.start(); // 读取Python脚本输出 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println("Python输出: " + line); } // 等待进程结束 int exitCode = process.waitFor(); System.out.println("Python脚本退出码: " + exitCode); } catch (Exception e) { e.printStackTrace(); } } } ``` **注意事项**: - 需保证Python环境变量已配置。 - 通过参数传递数据时需注意字符串转义。 - 若脚本执行时间较长,建议异步处理以避免阻塞主线程。 --- #### 2. 使用 **JEP**(Java Embedded Python) JEP提供直接嵌入Python解释器的能力,支持高效交互[^1]。 **步骤1:添加依赖(Maven)** ```xml <dependency> <groupId>black.ninia</groupId> <artifactId>jep</artifactId> <version>4.0.3</version> </dependency> ``` **步骤2:调用Python函数** ```java import jep.Jep; import jep.JepConfig; public class JepExample { public static void main(String[] args) { try (Jep jep = new Jep()) { // 执行Python代码 jep.eval("def add(a, b): return a + b"); // 调用Python函数 jep.eval("result = add(3,5)"); Object result = jep.getValue("result"); System.out.println("计算结果: " + result); // 输出8 } catch (JepException e) { e.printStackTrace(); } } } ``` **优势**: - 支持直接传递Java对象到Python环境(需类型转换)。 - 避免频繁启动进程的开销,适合高性能场景。 --- #### 3. 方法对比 | 方法 | 适用场景 | 性能 | 复杂度 | |---------------|--------------------------|-------|--------| | ProcessBuilder| 简单脚本调用 | 较低 | 低 | | JEP | 高频调用/复杂交互 | 高 | 中 | | JPype | 从Python调用Java(反向) | 中 | 高 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值