Simple haskell script with java
Try running a simple script in Haskell using Java code. ( window 10)
The haskell script looks like this:
import Data.Char(toUpper)
main = interact (map toUpper)
I made a simple.exe file with ghc and it works as expected for the cmd module. I wrote a simple string that replies with the same string in uppercase, and I can repeat this until I choose to stop the program.
But when I try to run this program through java, it won’t work like that. I can provide input, but in order to get the output, I need to close the input feed.
public class Main {
public static void main(String[] args) {
try {
Process process = new ProcessBuilder("simple").start();
InputStream processInputStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(processInputStream));
OutputStream processOutputStream = process.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(processOutputStream));
char[] bt = ("Hello").toCharArray();
writer.write(bt);
writer.flush();
writer.newLine();
processOutputStream.close(); -- Only works if I close output stream,.
System.out.println(reader.readLine());
}catch (IOException e) {
e.printStackTrace();
}
}
}
How to get output without closing the output feed in a Java program.
Restarting the process works, but the execution time is terrible.
I tried threading the program and the result is the same.
Solution
BufferedWriter
does not automatically refresh its output when you execute newLine().
So your Haskell program will not receive a newline and wait forever.
When you call close(),
all remaining buffered output is flushed (of course, you don’t want to do that).
So the solution should be
writer.write(bt);
writer.newLine();
writer.flush();
You can also use PrintWriter
, which has an auto-refresh line wrap option and understands strings (via the print
method), so there’s no need to mess with the characters[].
Finally, if you plan to send
or send a large amount of text at the same time, you may need to resize the buffer or use multiple threads to avoid deadlocks because the receive Java-side buffer is full and you are not currently reading it. Look at this thread for solutions.