Forum Bugs

Java Wrapper deadlocking while accessing in, out, and err streams

shougun
We recently upgraded from prince v 8 to the prince 20141212 alpha version (to pick up the OpenSSL SHA256 fix) and started having tuns of deadlocking issues while the java wrapper is waiting to read the prince output stream. Looking in other JAVA forums I found information about the use of process streams with the Runtime.getRuntime().exec function. in short, all access to the streams must be asynchronous in a separate thread to prevent blocking (www.coderanch.com/t/419192/java/java/Runtime-getRuntime-exec-String-command#1849168). The Java wrapper does not use threads to access the streams and may be the cause of our issues. (It may be due to writing to both the out and err streams, which is a new capability since v8.)

We are calling the convert(InputStream xmlInput, OutputStream pdfOutput) function in the wrapper. using the other versions is not a desirable option for us at this point as we want to keep file system access to a minimum.
mikeday
There is an updated Java wrapper for the alpha builds (prince-java-20141117.zip), have you tried this?
shougun
Yes, it fixed issues with adding multiple options, but still has the issue with blocking.
mikeday
That's unfortunate. The new logging system is supposed to avoid writing to the standard error stream until the standard output stream has been closed, to prevent this deadlock situation.

If you temporarily convert to an output file instead of a stream, do you notice any unusual errors or warnings in the log file?
shougun
No, using files instead of streams works without problems, and is the workaround we have put in place until this issue can be resolved.

It is interesting to note, that Prince will not accept an output file name that does not end in .pdf... I am not sure that should be required (though it does make the resulting file difficult to use without it) and I missed in the documentation where it states that is a requirement... in our situation the extension is irrelevant (because we are just streaming the resulting file without its name) and so i was tripped up on that for a while, because the resulting error messages are not added to the log file.

Edited by shougun

mikeday
The convert() method should be changed to specify the -o option explicitly, otherwise it interprets the second argument as another input filename, unless it ends with a .pdf extension. Sorry for the inconvenience, that is a left-over behaviour from an older version of Prince.
shougun
We are having issues with our workaround (of using the filesystem instead of streams) every once in a while, the JAVA wrapper fails to ever return and we get hung on waiting for it. Our server shows that the prince.exe process is still active. Manually killing the process fixes our issue until the next time prince fails to exit.

Is it possible that prince is not closing the error stream in some situations (we are using the alpha 20141212 version)?

Edited by shougun

mikeday
If it is hanging indefinitely, then there is a bigger problem than not closing the error stream. I'm wondering whether this is entirely unrelated to the deadlocking issue you were experiencing earlier. Did that ever work, or did it fail consistently every time?
shougun
it was consistently failing on our production server... I was able to get some use on my development machine, but saw the deadlock issues there as well. It became very apparent and failed consistently on my dev machine when I tried to get both the output stream and error stream from prince through the wrapper.

Our production server serializes the use of prince, so only one request at a time is ever sent to it.
mikeday
It became very apparent and failed consistently on my dev machine when I tried to get both the output stream and error stream from prince through the wrapper.

How exactly was it doing this? In the latest Prince alpha the intention is that the PDF output will be written to stdout, and log messages will be buffered, so nothing will be written to stderr. When the output file has been fully written, Prince will then write the buffered log messages to stderr, then terminate.

It is designed this way so the wrappers can read stdout first, then stderr, without needing multithreading or non-blocking reads.

Checking the code, perhaps it is possible that Prince is not actually closing stdout before writing the log messages to stderr, and the Java wrapper will still be blocking trying to read from stdout, causing the deadlock. We will investigate this further.

In the meantime, you could specify --structured-log=silent instead of --structured-log=buffered.

Please note that this issue should only affect the convert() methods that capture the PDF output in a stream; if Prince is writing directly to an output file then the deadlock should not be possible, as there is only one stream for the wrapper to read from.
mikeday
This issue has been fixed in Prince 10, available now. Sorry for the inconvenience! :)