JETTY-1460 suppress PrintWriter exceptions

This commit is contained in:
Jan Bartel 2011-12-15 20:19:04 +11:00
parent 300157fb2d
commit e515b5b7dc
5 changed files with 78 additions and 29 deletions

View File

@ -35,7 +35,8 @@ public class UncheckedPrintWriter extends PrintWriter
private static final Logger LOG = Log.getLogger(UncheckedPrintWriter.class); private static final Logger LOG = Log.getLogger(UncheckedPrintWriter.class);
private boolean _autoFlush = false; private boolean _autoFlush = false;
private boolean _throwUnchecked=true; private IOException _ioException;
private boolean _isClosed = false;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
@ -102,38 +103,45 @@ public class UncheckedPrintWriter extends PrintWriter
this(new BufferedWriter(new OutputStreamWriter(out)),autoFlush); this(new BufferedWriter(new OutputStreamWriter(out)),autoFlush);
} }
/* ------------------------------------------------------------ */
public boolean checkError()
{
return _ioException!=null || super.checkError();
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private void setError(Throwable th) private void setError(Throwable th)
{ {
setError();
if (_throwUnchecked) super.setError();
throw new RuntimeIOException(th);
if (th instanceof IOException)
_ioException=(IOException)th;
else
{
_ioException=new IOException(String.valueOf(th));
_ioException.initCause(th);
}
LOG.debug(th); LOG.debug(th);
} }
/* ------------------------------------------------------------ */
/** Are unchecked exceptions thrown.
* @return True if {@link RuntimeIOException}s are thrown
*/
public boolean isUncheckedPrintWriter()
{
return _throwUnchecked;
}
/* ------------------------------------------------------------ */ @Override
/** Set if unchecked exceptions are thrown protected void setError()
* @param uncheckedPrintWriter True if {@link RuntimeIOException}s are to be thrown
*/
public void setUncheckedPrintWriter(boolean uncheckedPrintWriter)
{ {
_throwUnchecked = uncheckedPrintWriter; setError(new IOException());
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Check to make sure that the stream has not been closed */ /** Check to make sure that the stream has not been closed */
private void isOpen() throws IOException private void isOpen() throws IOException
{ {
if (super.out == null) if (_ioException!=null)
throw new RuntimeIOException(_ioException);
if (_isClosed)
throw new IOException("Stream closed"); throw new IOException("Stream closed");
} }
@ -170,6 +178,7 @@ public class UncheckedPrintWriter extends PrintWriter
synchronized (lock) synchronized (lock)
{ {
out.close(); out.close();
_isClosed = true;
} }
} }
catch (IOException ex) catch (IOException ex)

View File

@ -356,7 +356,27 @@ public abstract class AbstractHttpConnection extends AbstractConnection
if (_writer==null) if (_writer==null)
{ {
_writer=new OutputWriter(); _writer=new OutputWriter();
if (_server.isUncheckedPrintWriter())
_printWriter=new UncheckedPrintWriter(_writer); _printWriter=new UncheckedPrintWriter(_writer);
else
_printWriter = new PrintWriter(_writer)
{
public void close()
{
synchronized (lock)
{
try
{
out.close();
}
catch (IOException e)
{
setError();
}
}
}
};
} }
_writer.setCharacterEncoding(encoding); _writer.setCharacterEncoding(encoding);
return _printWriter; return _printWriter;

View File

@ -76,6 +76,7 @@ public class Server extends HandlerWrapper implements Attributes
private int _maxCookieVersion=1; private int _maxCookieVersion=1;
private boolean _dumpAfterStart=false; private boolean _dumpAfterStart=false;
private boolean _dumpBeforeStop=false; private boolean _dumpBeforeStop=false;
private boolean _uncheckedPrintWriter=false;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -615,6 +616,20 @@ public class Server extends HandlerWrapper implements Attributes
dump(out,indent,TypeUtil.asList(getHandlers()),getBeans(),TypeUtil.asList(_connectors)); dump(out,indent,TypeUtil.asList(getHandlers()),getBeans(),TypeUtil.asList(_connectors));
} }
/* ------------------------------------------------------------ */
public boolean isUncheckedPrintWriter()
{
return _uncheckedPrintWriter;
}
/* ------------------------------------------------------------ */
public void setUncheckedPrintWriter(boolean unchecked)
{
_uncheckedPrintWriter=unchecked;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* A handler that can be gracefully shutdown. /* A handler that can be gracefully shutdown.
* Called by doStop if a {@link #setGracefulShutdown} period is set. * Called by doStop if a {@link #setGracefulShutdown} period is set.

View File

@ -741,6 +741,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
IO.copy(is,bout); IO.copy(is,bout);
byte[] b=bout.toByteArray(); byte[] b=bout.toByteArray();
System.err.println("OUTPUT: "+new String(b));
int i=0; int i=0;
while (b[i]!='Z') while (b[i]!='Z')
i++; i++;

View File

@ -337,6 +337,7 @@ public class ContextHandlerTest
public void testUncheckedPrintWriter() throws Exception public void testUncheckedPrintWriter() throws Exception
{ {
Server server = new Server(); Server server = new Server();
server.setUncheckedPrintWriter(true);
LocalConnector connector = new LocalConnector(); LocalConnector connector = new LocalConnector();
server.setConnectors(new Connector[] { connector }); server.setConnectors(new Connector[] { connector });
ContextHandler context = new ContextHandler("/"); ContextHandler context = new ContextHandler("/");
@ -422,7 +423,10 @@ public class ContextHandlerTest
writer.write("Goodbye cruel world\n"); writer.write("Goodbye cruel world\n");
writer.close(); writer.close();
response.flushBuffer(); response.flushBuffer();
writer.write("speaking from the dead"); //writer.write("speaking from the dead");
writer.write("give the printwriter a chance"); //should create an error
if (writer.checkError())
writer.write("didn't take the chance, will throw now"); //write after an error
} }
catch(Throwable th) catch(Throwable th)
{ {