Java program using ProcessBuilder with input and output streams does not work
I've looked at similar questions here on Stack Overflow, however, I can't seem to make this work.
I have a Java program that needs to use ProcessBuilder to load a C executable. The file just takes a string through the CLI and converts it to uppercase. The java program creates a system process with ProcessBuilder to manage this executable and must send the string and receive the converted one to print it to the CLI.
This is the code for uppercases.c :
#include <stdio.h>
int main(int argc, char *argv[]) {
char text[1024];
scanf("%s", &text[0]);
int i;
for(i = 0; i < strlen(text); i++) {
text[i] = toupper(text[i]);
}
printf("%s\n", text);
return 0;
}
I compiled it with
$ gcc uppercases.c -o uppercases
And launched it with
$ ./uppercases
Everything works perfectly. Now this is the code for Uppercase.java . I need to create an OutputStream to send a string to the C executable (uppercases) and then I create an InputStream to save its output and print it to the CLI:
public class Uppercase {
public static void main(String[] command) {
String textIn, textOut;
Scanner reader = new Scanner(System.in);
// This is what we want to send
System.out.println("Write something: ");
textIn = reader.nextLine();
try {
// Here I create a process to handle "uppercases"
Process process = new ProcessBuilder(command).start();
OutputStream os = process.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
// According to me, this will send the string to "uppercases"
bw.write(textIn);
bw.flush();
// This is to read the output of "uppercases"
InputStream is = process.getInputStream();
BufferedReader br = new BufferedReader (new InputStreamReader(is));
while ((textOut = br.readLine()) != null) {
System.out.println(textOut);
}
os.close();
is.close();
} catch (IOException e) {
System.out.println("I/O error:" + e.getMessage());
} catch (Exception e) {
System.out.println("Error:" + e.getMessage());
}
}
}
To compile, I type:
$ javac Uppercase.java
And execute:
$ java Uppercase ./uppercases
The problem is that when I type a line and press Enter, the cursor stays there forever, I enter enter again and nothing happens, and finally I need to press CTRL + C to exit. Any help would be appreciated.
source to share
Everything works fine with your java program with one exception: you are using BufferedWriter
which you clean up correctly, but since the line you are writing does not contain a newline, the C program is still expecting more input.
If you write:
// According to me, this will send the string to "uppercases"
bw.write(textIn);
bw.write("\n");
bw.flush();
Enough and the program exits normally.
But if you really want things to be bulletproof, you should close bw
to clearly indicate the subprocess shouldn't wait for more input:
// According to me, this will send the string to "uppercases"
bw.write(textIn);
bw.close();
Then the program ends normally (and correctly) even without a newline ending. Of course, in this case, the latter is os.close()
no longer needed, but it is still harmless.
source to share