我正试图从我的Java程序中启动一个python脚本-python脚本侦听Java程序中的套接字连接并用数据进行响应。为了做到这一点,我尝试使用ProcessBuilder API:
- 激活python虚拟机(位于我的工作目录中(
- 运行我的python脚本predictprobability.py,这样它就可以开始侦听来自我的java程序的连接。这就是我目前所拥有的:
public class MLClassifierProcess{
//bash location //activate python venv //python interpreter //script
final String[] command_to_run = new String[] { "/bin/bash", "-c", "/env/bin/activate;", "/env/bin/python","predictprobability.py;" };
public void startML(){
ProcessBuilder builder = new ProcessBuilder(command_to_run);
Process pr = null;
try {
pr = builder.start();
} catch (IOException ioException) {
System.out.println("error");
}
}
public static void main(String[] args){
MLClassifierProcess p = new MLClassifierProcess();
p.startML();
}
}
然而,当脚本predictprobability.py应该无限期地继续运行时,运行主函数会立即终止。我是ProcessBuilder API的新手,所以任何关于如何继续的指针都将非常感谢
如果您的Java程序退出,您启动的Python进程将退出,并且当父进程死亡时,子进程将被终止,除非它们已从该进程分离。
如果您希望Java程序一直运行到Python程序完成执行,那么您需要让Java代码适当地等待。以下是如何做到这一点:
public class MLClassifierProcess{
//bash location //activate python venv //python interpreter //script
final String[] command_to_run = new String[] { "/bin/bash", "-c", "/env/bin/activate;", "/env/bin/python","predictprobability.py;" };
public Process startML(){
ProcessBuilder builder = new ProcessBuilder(command_to_run);
Process pr = null;
try {
pr = builder.start();
} catch (IOException ioException) {
System.out.println("error");
}
return pr;
}
public static void main(String[] args){
MLClassifierProcess p = new MLClassifierProcess();
Process pr = p.startML();
if (pr != null)
pr.waitFor();
}
}
最终解决方案很简单:
Process process = Runtime.getRuntime().exec("<path/to/venv/python_interpreter> "+"path/to/scripytorun.py)
在我的情况下,成功的命令是
Process process = Runtime.getRuntime().exec( System.getProperty("user.dir")+"/env/bin/python "+System.getProperty("user.dir")+"/predictprobability.py");
process.waitFor();
@CryptoFool正确地指出,需要资源的绝对路径,因此System.getProperty("user.dir")
预先设置为相对路径