Java-在本地运行子进程,但是在Heroku上运行时失败并显示“管道中断”?

问题描述

作为背景,我在Heroku上部署了一个基于Java的discord机器人,使用了1个免费的dyno机器人。我需要运行一个.exe文件(stockfish 12可执行文件),将输入传递给它,并处理它的输出。我正在使用Java RunTime创建此Process,但是当我尝试使用flush()方法向其发送输入时,会抛出管道错误。我认为Heroku必须以某种方式关闭输入/输出流,因为此代码在本地运行良好。 Heroku在创建子流程上有限制吗?

app [worker.1]:Chess.player.ai.stockfish.exception.StockfishEngineException:java.io.IOException:管道损坏 应用程序[worker.1]:在Chess.player.ai.stockfish.engine.UCIEngine.sendCommand(UCIEngine.java:39) 应用程式[worker.1]:在Chess.player.ai.stockfish.engine.UCIEngine.passOption(UCIEngine.java:77) 应用程序[worker.1]:在棋牌游戏中。 应用程式[worker.1]:在围棋下棋(Stockfish.java:13) 应用程序[worker.1]:在Chess.player.ai.stockfish.StockFishClient。(StockFishClient.java:21) 应用程序[worker.1]:在Chess.player.ai.stockfish.StockFishClient $ Builder.build(StockFishClient.java:80)

编辑:我试图通过对单个命令进行硬编码来简化程序,但仍然无法通过writer.flush()行。什么都没打印。

Process process = new ProcessBuilder().command("bin/stockfish_20090216_x64_bmi2.exe").start();

StringBuilder output = new StringBuilder();
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getoutputStream()));
writer.write("position fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" + "\n");
writer.write("go movetime 1000");
writer.flush();

String line;
while ((line = input.readLine()) != null) {
    output.append(line + "\n");
}

int exitVal = process.waitFor();
if (exitVal == 0) {
    System.out.println("success");
    System.out.println(output.toString());
}
else {
    System.out.println("error");
}

解决方法

output流将自行关闭。运行命令时,请创建一个新进程,否则此命令必须阻止流并等待输入。

推荐ProcessBuilder,它更容易配置:

new ProcessBuilder().command("cmd.exe","/c","command")
                    .directory(new File(path))
                    .redirectInput(new File(path,"input.txt"))
                    .redirectOutput(new File(path,"output.txt"))
                    .redirectError(new File(path,"runtime_error.txt"))
                    .start()
                    .waitFor();
,

结果是我使用了错误的二进制文件。 Stockfish二进制文件有许多不同的格式,显然,适用于本机的二进制文件不适用于Heroku。