【问题标题】:Cannot run python script from java jar无法从 java jar 运行 python 脚本
【发布时间】:2020-09-14 21:59:24
【问题描述】:

在 IntelliJ 中工作时一切正常,但在我构建 jar 后它停止了。一开始只是我忘了把它放在jar build config中,但是现在确定它在那里之后,我仍然无法运行它。这些是我尝试的方法:

InputStream script = mainView.class.getResourceAsStream("vizualize3D.py");
Process process = new ProcessBuilder("python3", "-").start() ;

Process p1 = Runtime.getRuntime().exec("python3 " + script);

Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("python3 " + mainView.class.getResourceAsStream("vizualize3D.py"));

尽管资源中有主题,但它们都不起作用。我还尝试在 IntelliJ 项目中指定它的路径,它可以工作,但只有在我从 jar 启动它之后从 IntelliJ 运行时它才不会。

编辑1: 对于不了解py文件的人在jar文件中

【问题讨论】:

  • visuzlize3d.py是和jar文件在同一个目录吗?你试过用visualize3D.py的绝对路径吗?
  • @AkibRhast 看看edit1
  • Python 不知道如何从 jar 文件中提取脚本。您必须将它作为单独的文件放在 jar 文件旁边。
  • @ThomasKläger 您可以将其流式传输到 python 解释器的标准输入。

标签: java python javafx jar executable-jar


【解决方案1】:

涉及您尝试执行"python3 "+script 的选项及其等效项均无效。 scriptInputStream,而不是文件系统上的路径,因此简单地将其与 String 连接不会给您任何有意义的东西。此外,由于您的脚本不在其自己的文件中,并且 python 解释器没有简单的方法来提取它,因此像这样简单地调用它是行不通的。

然而,你可以做的是执行

python3 -

这里的- 选项(至少在类似BSD 的系统上)表示“从标准输入读取,并将其解释为脚本”。然后,在 Java 端,您可以将 jar 打包的资源作为流读取,并将其通过管道传输到 python 进程的标准输入。

有关为资源选择正确路径的详细信息,请参阅How do I determine the correct path for FXML files, CSS files, Images, and other resources needed by my JavaFX Application?

下面的脚本简单地放在与类相同的包中,对我有用:

PythonRunner.java:

package example.python;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

public class PythonRunner {

    public static void main(String[] args) throws Exception {

        String pythonInterpreter = "/usr/bin/python3" ; // default
        if (args.length > 0) {
            pythonInterpreter = args[0] ;
        }

        InputStream script = PythonRunner.class.getResourceAsStream("script.py");
        Process pythonProcess = new ProcessBuilder(pythonInterpreter, "-")
                .start();

        // This thread reads the output from the process and 
        // processes it (in this case just dumps it to standard out)
        new Thread(() ->  {
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(pythonProcess.getInputStream()))) {

                for (String line ; (line = reader.readLine()) != null ;) {
                    System.out.println(line);
                }
            } catch (IOException exc) {
                exc.printStackTrace();
            }
        }).start();

        // read the script from the resource, and pipe it to the
        // python process's standard input (which will be read because
        // of the '-' option)
        OutputStream stdin = pythonProcess.getOutputStream();
        byte[] buffer = new byte[1024];
        for (int read = 0 ; read >= 0 ; read = script.read(buffer)) {
            stdin.write(buffer, 0, read);
        }
        stdin.close();
    }

}

脚本.py:

import sys

for i in range(10):
    print("Spam")

sys.exit(0)

清单.MF

Manifest-Version: 1.0
Main-Class: example.python.PythonRunner

Eclipse 布局:

Jar内容及运行结果:

$ jar tf runPython.jar 
META-INF/MANIFEST.MF
example/python/PythonRunner.class
example/python/script.py
$ java -jar runPython.jar 
Spam
Spam
Spam
Spam
Spam
Spam
Spam
Spam
Spam
Spam
$

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-14
    • 2017-05-22
    • 1970-01-01
    • 1970-01-01
    • 2015-11-30
    • 2010-12-08
    • 1970-01-01
    • 2021-09-13
    相关资源
    最近更新 更多