1

I'm writing a wrapper for the command line based headless server of the game Factorio. I'm using a ProcessBuilder and getting the stdout of the server and am using the rcon connection (long story, stdin wasn't working) to communicate with it. I've gotten it nearly completed up until the point where I was going to package up the jar and run it on the physical server. This is when I noticed that running the jar instead of running from the IDE (Intelij) prevents any output from the server from coming through. I did some more snooping and found that whenever I am using .getInputStream() from the process, the server's output is only sent if the program was launched alongisde the console (java.exe) and doesn't get sent at all if the program was launched without it (javaw.exe).

I tested .getInputStream() with cmd.exe and it works just fine with both java.exe and javaw.exe. I also check to see if the code was following some flow that I wasn't expecting when ran outside of the IDE but it blocks on read.readLine() as if it's waiting for input but not receiving anything.

The process is initialized here:

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));

Later, the input is handled by the gui and is sent via rcon (after the server has been fully initialized), and the output is read and printed to the gui's feed, JTextArea, here:

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());}
        }

The application should have printed out the server's output such as all the initializing text about modloading, connecting to the matchmaking server, etc. like it does in the IDE and when java.exe is used. Instead it doesn't output anything at all but the process continues to run and the server can be connected to in-game after it's done initializing.

XiiDraco
  • 11
  • 2
  • java.exe most likely is blocked withing the STDIN-OUT context until the process is terminated. Using javaw.exe spawns a new independent process so you lose the IO environment context. Most likely case. – Whome Jun 02 '19 at 13:43
  • Hmmm, how would that explain it working with cmd, powershell, and other programs though? – XiiDraco Jun 02 '19 at 18:02

0 Answers0