无法从 java jar 中 运行 python 脚本
Cannot run python script from java jar
在 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"));
None 的主题作品,尽管它在资源中。我还尝试在 IntelliJ 项目中指定它的路径并且它有效,但只有当我从 jar 启动它后来自 IntelliJ 的 运行 它才不起作用。
编辑1:
对于不理解 py 文件在 jar 文件中的人
None 涉及您尝试执行 "python3 "+script
的选项和等效项将起作用。 script
是一个 InputStream
,不是文件系统上的路径,所以简单地将它与 String
连接起来不会给你任何有意义的东西。此外,由于您的脚本不在其自己的文件中,并且 python 解释器没有简单的方法来提取它,因此像这样简单地调用它是行不通的。
但是,您可以执行
python3 -
此处的 -
选项(至少在类 BSD 系统上)表示 "read from standard input, and interpret it as a script"。然后,在 Java 端,您可以将 jar 打包的资源作为流读取并将其通过管道传输到 python 进程的标准输入。
有关为资源选择正确路径的详细信息,请参阅 。
下面的脚本与 class 放在同一个包中,对我有用:
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();
}
}
script.py:
import sys
for i in range(10):
print("Spam")
sys.exit(0)
MANIFEST.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
$
在 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"));
None 的主题作品,尽管它在资源中。我还尝试在 IntelliJ 项目中指定它的路径并且它有效,但只有当我从 jar 启动它后来自 IntelliJ 的 运行 它才不起作用。
编辑1: 对于不理解 py 文件在 jar 文件中的人
None 涉及您尝试执行 "python3 "+script
的选项和等效项将起作用。 script
是一个 InputStream
,不是文件系统上的路径,所以简单地将它与 String
连接起来不会给你任何有意义的东西。此外,由于您的脚本不在其自己的文件中,并且 python 解释器没有简单的方法来提取它,因此像这样简单地调用它是行不通的。
但是,您可以执行
python3 -
此处的 -
选项(至少在类 BSD 系统上)表示 "read from standard input, and interpret it as a script"。然后,在 Java 端,您可以将 jar 打包的资源作为流读取并将其通过管道传输到 python 进程的标准输入。
有关为资源选择正确路径的详细信息,请参阅
下面的脚本与 class 放在同一个包中,对我有用:
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();
}
}
script.py:
import sys
for i in range(10):
print("Spam")
sys.exit(0)
MANIFEST.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
$