Search code examples
javablocking

Piped Stream Issue in Freemarker


I need to load and process a template in freemarker. I am using a piped stream to read back the generated result by freemarker.

Sample code:

PipedInputStream pi = new PipedInputStream();
PipedOutputStream po = new PipedOutputStream(pi);
Writer writer = new OutputStreamWriter(po);
configuration.getTemplate("xx").process(rootMap, writer);

The issue is that sometimes it's freezing inside freemarker procsss method. No Error, no Exception, but it's not returning back from the process method.

If I convert the piped stream to a ByteArray stream, it works fine.

Am I using piped stream in correct way?


Solution

  • No, piped streams are designed to pass data between two threads. There is only a small buffer between the ends of the pipe. If you write into the piped output stream, your thread will be blocked if the buffer is full until another thread will read from the corresponding piped input stream. This will not work with just one thread.

    From the Javadoc:

    Typically, data is read from a PipedInputStream object by one thread and data is written to the corresponding PipedOutputStream by some other thread.

    So for small templates just use a StringWriter, for large ones you may use a FileWriter on a temp file created by File.createTempFile().