Hi all, > > An alternative that I could imagine, would be to create a class (that has a > boolean flag) which extends OutputStream, and decorates another OutputStream > that is given to the class in the constructor (that would be the > OutputStream from the servlet's response). This class would pass all calls > to it to the other OutputStream (as long as the flag is true), and as soon > as close() or another special method is called, it sets the flag to false, > which causes all other methods to do nothing (or throw an IOException). That > way, Tomcat's OutputStream would also be protected from future calls > from the ImageIO. >
I now use a OutputStream decorator like this when calling ImageIO.write(): public class ImageIOBetterOutputStream extends OutputStream { private OutputStream out; // the actual stream private volatile boolean isActive = true; public ImageIOBetterOutputStream (OutputStream out) { this.out = out; } @Override public void close() throws IOException { if (isActive) { isActive = false; // deactivate try { out.close(); } finally { out = null; } } } @Override public void flush() throws IOException { // do nothing } @Override public void write(byte[] b, int off, int len) throws IOException { if (isActive) { out.write(b, off, len); } } [...] (overwrite the other methods the same way) } That way, I don't have to use a ByteArrayOutputStream to buffer the contents in memory, and Tomcat's OutputStream is also protected from future calls to flush() from the ImageIO (I just have to make sure that the call to close() is inside a finally-block). (If flush() is the only method that the ImageIO calls after an IOException, it probably would be enough to overwrite flush() only). Since I'm using this class as OutputStream for the ImageIO, there also haven't been any more errors. > I agree that this behavior of the ImageIO is very strange (flushing the > OutputStream when the ImageWriter gets garbage-collected, if an IOException > was thrown when the IIO previously tried to write to the stream). > However, it seems also a bit strange to me that Tomcat is recycling OutputStreams, > because in my understanding, once an OutputStream is closed, it should > be impossible to do any further write() calls to it. > > May I ask, what is the particular reason for Tomcat to recycle > OutputStreams? Does anyone have a clue about this? I can understand recycling objects like the Request/Response objects (e.g. if they contain lots of fields), but at the moment I don't have an idea why it would be useful to recycle OutputStream objects. > Also, is there any hint to this on the Tomcat documentation/wiki? Because I > don't think it would be unusual to dynamically generate images and > serve them to clients using the ImageIO, and I think it could be a bit > frustrating to find the actual problem if one doesn't know this. I couldn't find any hints about this in the Tomcat documentation/wiki, but I think it should be mentioned somewhere. Of course, the behavior of the ImageIO is strange, but Tomcat's recycling of OutputStreams enable the errors when using the ImageIO. If it is desired, maybe I could contribute something to this topic for docs/wiki? Regards, Konstantin Preißer --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org