我正在为游戏Factorio的基于命令行的无头服务器编写包装。我正在使用ProcessBuilder并获取服务器的标准输出,并正在使用rcon连接(长话短说,stdin无法正常工作)与之通信。我几乎完成了它,直到要打包jar并在物理服务器上运行它为止。这是当我注意到运行jar而不是从IDE(Intelij)运行会阻止服务器的任何输出通过时。我进行了更多侦听,发现每当我在进程中使用.getInputStream()时,仅在程序沿控制台(java.exe)启动时才发送服务器输出,而在程序执行时根本不发送是在没有它的情况下启动的(javaw.exe)。
我用cmd.exe测试了.getInputStream(),它与java.exe和javaw.exe都可以正常工作。我还检查了代码是否遵循了我在IDE之外运行时所期望的流程,但是它在read.readLine()上阻塞,就好像它在等待输入但没有收到任何东西。
此过程在此处初始化:
ProcessBuilder pb = new ProcessBuilder(gameExecutablePath, "--start-server", saveLocation + "\\" + saveName, "--server-settings", serverSettingsLocation + "\\" + serverSettingsName, "-c", serverConfigLocation + "\\" + serverConfigName, "--rcon-port", "" + rconPort, "--rcon-password", "" + rconPasskey);
pb.redirectErrorStream(true);
try
{
myProcess = pb.start();
}catch(Exception e){e.printStackTrace();}
if(myProcess == null) { stop();}
OutputStream serverInput = myProcess.getOutputStream();
write = new BufferedWriter(new OutputStreamWriter(serverInput));
InputStream serverOutput = myProcess.getInputStream();
read = new BufferedReader(new InputStreamReader(serverOutput));
稍后,输入由gui处理,并通过rcon发送(在服务器已完全初始化之后),输出被读取并打印到gui的提要JTextArea,在这里:
while(serverRunning)
{
try
{
String line = "" + read.readLine();
if(line == null)
{
continue;
}
line = line.trim();
if(line.contains("Opening socket for broadcast"))
{
serverInitialized = true;
initializeRCONConnection();
}
synchronized(serverFeedStringBuilder)
{
printToServerFeed(line);
}
}catch(Exception e){e.printStackTrace();printToServerFeed(e.getMessage());}
}
应用程序应该已经打印出服务器的输出,例如有关modloading的所有初始化文本,连接到配对服务器等,就像它在IDE中以及使用java.exe时所做的那样。取而代之的是,它什么也不输出,但是进程会继续运行,并且服务器可以在初始化完成后连接到游戏中。