Writing to InputStream of a Java Process

This is an example which maybe can helps someone

import java.io.IOException;
import java.io.File;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws IOException {
        String[] commands = {"C:/windows/system32/cmd.exe"};
        ProcessBuilder builder = new ProcessBuilder(commands);
        builder.directory(new File("C:/windows/system32"));
        Process process = builder.start();

        OutputStream stdin = process.getOutputStream();
        InputStream stdout = process.getInputStream();
        InputStream stderr = process.getErrorStream();

        BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
        BufferedReader error = new BufferedReader(new InputStreamReader(stderr));

        new Thread(() -> {
            String read;
            try {
                while ((read = reader.readLine()) != null) {
                    System.out.println(read);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            String read;
            try {
                while ((read = error.readLine()) != null) {
                    System.out.println(read);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            while (true) {
                try {
                    Scanner scanner = new Scanner(System.in);
                    writer.write(scanner.nextLine());
                    writer.newLine();
                    writer.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

The Process OutputStream (our point of view) is the STDIN from the process point of view

OutputStream stdin = process.getOutputStream(); // write to this

So what you have should be correct.

My driver (apply your own best practices with try-with-resources statements)

public class ProcessWriter {
    public static void main(String[] args) throws Exception {
        ProcessBuilder builder = new ProcessBuilder("java", "Test");
        builder.directory(new File("C:\\Users\\sotirios.delimanolis\\Downloads"));
        Process process = builder.start();

        OutputStream stdin = process.getOutputStream(); // <- Eh?
        InputStream stdout = process.getInputStream();

        BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));

        writer.write("Sup buddy");
        writer.flush();
        writer.close();

        Scanner scanner = new Scanner(stdout);
        while (scanner.hasNextLine()) {
            System.out.println(scanner.nextLine());
        }
    }
}

My application

public class Test {

    public static void main(String[] args) throws Exception {
        Scanner console = new Scanner(System.in);
        System.out.println("heello World");
        while(console.hasNextLine()) {
            System.out.println(console.nextLine());
        }
    }
}

Running the driver prints

heello World
Sup buddy

For some reason I need the close(). The flush() alone won't do it.

Edit It also works if instead of the close() you provide a \n.

So with

writer.write("Sup buddy");
writer.write("\n");
writer.write("this is more\n");
writer.flush();    

the driver prints

heello World
Sup buddy
this is more