如何通过 Java ProcessBuilder 在 python 脚本中使用包(例如转换器)
How can I use a package (such as transformers) in python script through Java ProcessBuilder
为了连接管道的 Java 和 Python 部分,我正在尝试不同的方法。目前我正在 Java:
中使用以下代码尝试 ProcessBuilder 方法
import java.io.*;
import java.util.*;
public class Tryout {
public static void main(String []args) {
try {
var processBuilder = new ProcessBuilder("/usr/bin/python3", "tryout.py", "example string for testing purposes");
processBuilder.redirectErrorStream(true);
var process = processBuilder.start();
process.waitFor();
System.out.println(process);
try (var reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
catch(IOException e){
System.out.println(e.getMessage());
}
catch(InterruptedException e){
System.out.println(e.getMessage());
}
}
}
以及 python 的代码:
from transformers import BertTokenizer
import sys
print("hello from python!")
input_string = sys.argv[1]
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
tokens = tokenizer(input_string, padding='max_length', max_length=512, truncation=True, return_tensors="np")
print(list(tokens['input_ids'][0]))
print(list(tokens['attention_mask'][0]))
但是,这给了我错误:ModuleNotFoundError: No module named 'transformers'
。
在您询问之前,转换器包已安装,并且 python 脚本 运行 在从命令行调用时正常。
我的问题是:如何在 JVM 中包含这些模块?
我不完全理解 ProcessBuilder 的技术细节,并假设它会 运行 在命令行中使用我的本地 python 环境,但显然情况并非如此。
确保用于 JVM 启动的 PYTHONPATH 与从 shell 启动它的 python 相同。这将确保 python 运行 时使用的环境作为 Java 的 sub-process 将与 运行 时直接来自 shell 的环境匹配] / 终端机。
编辑
对于有同样问题的其他人,这里有一些方法可以检查或设置 Java -> Python 调用的 PYTHONPATH。默认情况下 Java 传递从它自己的环境变量中使用的值:
System.out.println("getenv().PYTHONPATH="+System.getenv("PYTHONPATH"));
或者为 ProcessBuilder
启动设置 PYTHONPATH:
String pypath = List.of(Path.of("somedir"), Path.of("anotherdir"))
.stream().map(Path::toAbsolutePath).map(Path::toString)
.collect(Collectors.joining(File.pathSeparator));
pb.environment().put("PYTHONPATH", pypath);
System.out.println("environment().PYTHONPATH="+pb.environment().get("PYTHONPATH"));
检查现有 python 脚本中使用的值:
# import os
print("PYTHONPATH", os.getenv('PYTHONPATH'))
为了连接管道的 Java 和 Python 部分,我正在尝试不同的方法。目前我正在 Java:
中使用以下代码尝试 ProcessBuilder 方法import java.io.*;
import java.util.*;
public class Tryout {
public static void main(String []args) {
try {
var processBuilder = new ProcessBuilder("/usr/bin/python3", "tryout.py", "example string for testing purposes");
processBuilder.redirectErrorStream(true);
var process = processBuilder.start();
process.waitFor();
System.out.println(process);
try (var reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
catch(IOException e){
System.out.println(e.getMessage());
}
catch(InterruptedException e){
System.out.println(e.getMessage());
}
}
}
以及 python 的代码:
from transformers import BertTokenizer
import sys
print("hello from python!")
input_string = sys.argv[1]
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
tokens = tokenizer(input_string, padding='max_length', max_length=512, truncation=True, return_tensors="np")
print(list(tokens['input_ids'][0]))
print(list(tokens['attention_mask'][0]))
但是,这给了我错误:ModuleNotFoundError: No module named 'transformers'
。
在您询问之前,转换器包已安装,并且 python 脚本 运行 在从命令行调用时正常。
我的问题是:如何在 JVM 中包含这些模块?
我不完全理解 ProcessBuilder 的技术细节,并假设它会 运行 在命令行中使用我的本地 python 环境,但显然情况并非如此。
确保用于 JVM 启动的 PYTHONPATH 与从 shell 启动它的 python 相同。这将确保 python 运行 时使用的环境作为 Java 的 sub-process 将与 运行 时直接来自 shell 的环境匹配] / 终端机。
编辑
对于有同样问题的其他人,这里有一些方法可以检查或设置 Java -> Python 调用的 PYTHONPATH。默认情况下 Java 传递从它自己的环境变量中使用的值:
System.out.println("getenv().PYTHONPATH="+System.getenv("PYTHONPATH"));
或者为 ProcessBuilder
启动设置 PYTHONPATH:
String pypath = List.of(Path.of("somedir"), Path.of("anotherdir"))
.stream().map(Path::toAbsolutePath).map(Path::toString)
.collect(Collectors.joining(File.pathSeparator));
pb.environment().put("PYTHONPATH", pypath);
System.out.println("environment().PYTHONPATH="+pb.environment().get("PYTHONPATH"));
检查现有 python 脚本中使用的值:
# import os
print("PYTHONPATH", os.getenv('PYTHONPATH'))