从Python调用java程序(带参数)并将结果返回给Python

问题描述 投票:0回答:2

我必须从 Python 执行一个 java 文件(传递单个参数),执行后将结果返回给调用它的脚本。我编写了一个小的 java 测试程序,它接受一个参数并将一些内容打印到标准输出。这是java程序

import java.util.*;
class TestX
{
       public static void main(String args[])
       {
            String someString = "Your input";
            System.out.println(someString + " " + args[0]);
            int resultOfSomething = 45;
            String someOutput = "Program's output is " + resultOfSomething;
            System.out.println(someOutput);
       }
}

这是调用java程序的Python脚本

import os.path,subprocess
from subprocess import STDOUT,PIPE

def compile_java(java_file):
    subprocess.check_call(['javac', java_file])

def execute_java(java_file):
    java_class,ext = os.path.splitext(java_file)
    cmd = ['java', java_class]
    proc = subprocess.Popen(cmd, stdout=PIPE, stderr=STDOUT)
    stdout,stderr = proc.communicate(input='SomeInputstring')
    print ('This was "' + stdout + '"')

compile_java('TestX.java')
execute_java('TestX.java')

我应该提一下,我对java不熟悉。我通过这个命令 javac TestX.java 编译了这个小java程序。这创建了一个类文件。当我使用

java TestX SomeTestString
从命令行运行 java 程序时,小型 java 程序按预期工作并向控制台输出一些文本。

现在问题来了;当我使用上面的代码从 Python 运行相同的 java 程序时 - 1)出现错误

This was "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0

        at TestX.main(TestX.java:7)
"

当我注释掉Python程序中的

print ('This was "' + stdout + '"')
行时,Python程序运行并且似乎执行了java程序,但没有任何内容返回到控制台。我在这里遗漏了一些非常简单的东西,或者这只是我犯的一个愚蠢的错误。有什么指点吗?谢谢。

我尝试了几种不同的方法来输出结果,例如使用 printf,甚至使用此类 StdOut。他们的行为似乎都一样。

如果我要简单地解释一下,那就是这个; 我的 Python 脚本应该使用单个参数调用 java 程序。 java 程序接受输入,执行某些函数并返回一个结果,我应该能够从调用它的 Python 程序中读取该结果。

java python subprocess popen
2个回答
3
投票

命令行参数不是标准输入。

args[0]
是命令行参数。你应该能够这样做

cmd = ['java', java_class, 'SomeInputString']

0
投票

对于您的要求(执行从Python传递单个参数的java文件,并在执行后将结果返回给调用它的脚本),不推荐Popen。这是因为它是非阻塞的。该代码不会等待输出返回。对于 Python > 3.7,请使用 subprocess.run() 命令。

result = subprocess.run(
    ['java', '-cp', EXTERNAL_JAR_PATHS, 'MyJavaCode.java'],
    capture_output = True,
    text = True,
    cwd = PATH_TO_CODE
)

result.stdout 提供程序输出,result.stderr 提供错误信息(如果有)。

为什么这比调试 Popen 代码更好:

  • 更简单且适合您的要求。无需处理流、死锁问题等
  • subprocess.run 是> 3.7 python 版本推荐的默认方法
  • Popen 创建一个新进程和额外的逻辑以确保新进程正确终止等需要考虑

话虽如此,在你的情况下,埃利奥特正确解决了当前的问题/错误。我的方法解决了上一段中概述的更大要求

© www.soinside.com 2019 - 2024. All rights reserved.