unsubscribe
 

> From: are...@yahoo-inc.com
> To: users@tomcat.apache.org
> CC: laraa...@yahoo-inc.com
> Date: Thu, 9 Feb 2012 12:07:15 -0800
> Subject: RE: Cores with FlushableGzipOutputStream
> 
> Try again now that I'm subscribed.
> 
> 
> > -----Original Message-----
> > From: Allen Reese
> > Sent: Thursday, February 09, 2012 12:03 PM
> > To: 'users@tomcat.apache.org'
> > Cc: Lars Anderson
> > Subject: Cores with FlushableGzipOutputStream
> > 
> > We've just upgraded from tomcat 6.0.33 to 6.0.35 and started having the
> > JVM core on our production boxes.
> > 
> > I'm trying to determine what the next course of action should be here.
> > I have an Oracle Support contract, but they don't seem to see this as a
> > JVM issue, and blame it on a native lib.
> > 
> > 
> > Thanks.
> > 
> > Allen Reese
> > Core Platforms
> > Yahoo!, Inc.
> > 
> > Running on linux x86-64, jdk 6u27, 6u29, 6u30, 7u2
> > 
> > We run several tests and the output is:
> > 
> > Jdk | Version | flags
> > |
> > 6u30 | 6.0.33 | compression enabled
> > | works
> > 6u30 | 6.0.35 | compression enabled
> > | cores
> > 6u30 | 6.0.35 | compression disabled
> > | works
> > 6u30 | 6.0.35 | Remove changes to FlushableGzipOutputStream [1]
> > | works
> > 6u30 | 6.0.35 | -Dsun.zip.disableMemoryMapping=true
> > | cores
> > 
> > 7u2 | 6.0.35 | compression enabled
> > | cores
> > 7u2 | 6.0.35 | compression disabled
> > |
> > 7u2 | 6.0.35 | Remove changes to FlushableGzipOutputStream [1]
> > |
> > 7u2 | 6.0.35 | -Dsun.zip.disableMemoryMapping=true
> > | cores
> > 
> > https://issues.apache.org/bugzilla/show_bug.cgi?id=52121
> > 
> > I filed an SR with Oracle, as this looks like a JVM bug and got the
> > following response:
> > 
> > Generic Note
> > ------------------------
> > Hi Allen,
> > 
> > Thank you for sending the hotspot error logs (hs_err_pid<pid>). Each
> > one of them has verbiage that indicates the problem is not with Java,
> > but with native code:
> > 
> > # Problematic frame:
> > # C [libzip.so+0x77e3] char+0xa3
> > #
> > # If you would like to submit a bug report, please visit:
> > # http://java.sun.com/webapps/bugreport/crash.jsp
> > # The crash happened outside the Java Virtual Machine in native code.
> > # See problematic frame for where to report the bug.
> > #
> > 
> > The case description also noted:
> > 
> > Rolling back this patch to tomcat increases stability:
> > http://svn.apache.org/viewvc?view=revision&revision=1197382
> > 
> > Again, this points to software other than Java. The Java defect
> > mentioned, 4813885, was fixed in June of 2009.
> > =====================
> > 
> > Allen Reese
> > Core Platforms
> > Yahoo!, Inc.
> > 
> > [1]: Patch to remove changes to FlushableGZIPOutputStream from 6.0.35.
> > 
> > --- apache-tomcat-6.0.35-
> > src/java/org/apache/coyote/http11/filters/FlushableGZIPOutputStream.jav
> > a 2011-11-28 02:22:45.000000000 -0800
> > +++ apache-tomcat-6.0.33-
> > src/java/org/apache/coyote/http11/filters/FlushableGZIPOutputStream.jav
> > a 2011-08-16 05:26:14.000000000 -0700
> > @@ -35,93 +35,58 @@
> > super(os);
> > }
> > 
> > + private static final byte[] EMPTYBYTEARRAY = new byte[0];
> > + private boolean hasData = false;
> > +
> > /**
> > - * It is used to reserve one byte of real data so that it can be
> > used when
> > - * flushing the stream.
> > + * Here we make sure we have received data, so that the header has
> > been for
> > + * sure written to the output stream already.
> > */
> > - private byte[] lastByte = new byte[1];
> > - private boolean hasLastByte = false;
> > -
> > - @Override
> > - public void write(byte[] bytes) throws IOException {
> > - write(bytes, 0, bytes.length);
> > - }
> > -
> > @Override
> > - public synchronized void write(byte[] bytes, int offset, int
> > length)
> > + public synchronized void write(byte[] bytes, int i, int i1)
> > throws IOException {
> > - if (length > 0) {
> > - flushLastByte();
> > - if (length > 1) {
> > - super.write(bytes, offset, length - 1);
> > - }
> > - rememberLastByte(bytes[offset + length - 1]);
> > - }
> > + super.write(bytes, i, i1);
> > + hasData = true;
> > }
> > 
> > @Override
> > public synchronized void write(int i) throws IOException {
> > - flushLastByte();
> > - rememberLastByte((byte) i);
> > + super.write(i);
> > + hasData = true;
> > }
> > 
> > @Override
> > - public synchronized void finish() throws IOException {
> > - try {
> > - flushLastByte();
> > - } catch (IOException ignore) {
> > - // If our write failed, then trailer write in finish()
> > will fail
> > - // with IOException as well, but it will leave Deflater in
> > more
> > - // consistent state.
> > - }
> > - super.finish();
> > + public synchronized void write(byte[] bytes) throws IOException {
> > + super.write(bytes);
> > + hasData = true;
> > }
> > 
> > @Override
> > - public synchronized void close() throws IOException {
> > - try {
> > - flushLastByte();
> > - } catch (IOException ignored) {
> > - // Ignore. As OutputStream#close() says, the contract of
> > close()
> > - // is to close the stream. It does not matter much if the
> > - // stream is not writable any more.
> > + public synchronized void flush() throws IOException {
> > + if (!hasData) {
> > + return; // do not allow the gzip header to be flushed on
> > its own
> > }
> > - super.close();
> > - }
> > 
> > - private void rememberLastByte(byte b) {
> > - lastByte[0] = b;
> > - hasLastByte = true;
> > - }
> > + // trick the deflater to flush
> > + /**
> > + * Now this is tricky: We force the Deflater to flush its data
> > by
> > + * switching compression level. As yet, a perplexingly simple
> > workaround
> > + * for
> > + *
> > http://developer.java.sun.com/developer/bugParade/bugs/4255743.html
> > + */
> > + if (!def.finished()) {
> > + def.setInput(EMPTYBYTEARRAY, 0, 0);
> > 
> > - private void flushLastByte() throws IOException {
> > - if (hasLastByte) {
> > - // Clear the flag first, because write() may fail
> > - hasLastByte = false;
> > - super.write(lastByte, 0, 1);
> > - }
> > - }
> > + def.setLevel(Deflater.NO_COMPRESSION);
> > + deflate();
> > 
> > - @Override
> > - public synchronized void flush() throws IOException {
> > - if (hasLastByte) {
> > - // - do not allow the gzip header to be flushed on its own
> > - // - do not do anything if there is no data to send
> > -
> > - // trick the deflater to flush
> > - /**
> > - * Now this is tricky: We force the Deflater to flush its
> > data by
> > - * switching compression level. As yet, a perplexingly
> > simple workaround
> > - * for
> > - *
> > http://developer.java.sun.com/developer/bugParade/bugs/4255743.html
> > - */
> > - if (!def.finished()) {
> > - def.setLevel(Deflater.NO_COMPRESSION);
> > - flushLastByte();
> > - def.setLevel(Deflater.DEFAULT_COMPRESSION);
> > - }
> > + def.setLevel(Deflater.DEFAULT_COMPRESSION);
> > + deflate();
> > +
> > + out.flush();
> > }
> > - out.flush();
> > +
> > + hasData = false; // no more data to flush
> > }
> > 
> > /*
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
> 
                                          

Reply via email to