diff --git a/tomcat-9.0-disable-osgi-build.patch b/tomcat-9.0-osgi-build.patch similarity index 100% rename from tomcat-9.0-disable-osgi-build.patch rename to tomcat-9.0-osgi-build.patch diff --git a/tomcat-9.0.30-java8compat.patch b/tomcat-9.0.30-java8compat.patch new file mode 100644 index 0000000..5ace0e9 --- /dev/null +++ b/tomcat-9.0.30-java8compat.patch @@ -0,0 +1,3341 @@ +--- apache-tomcat-9.0.30-src/java/org/apache/catalina/connector/InputBuffer.java 2019-12-07 17:52:30.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/catalina/connector/InputBuffer.java 2020-01-20 14:01:46.983405048 +0100 +@@ -389,10 +389,10 @@ + } + int n = Math.min(to.remaining(), bb.remaining()); + int orgLimit = bb.limit(); +- bb.limit(bb.position() + n); ++ ((Buffer)bb).limit(bb.position() + n); + to.put(bb); +- bb.limit(orgLimit); +- to.limit(to.position()).position(to.position() - n); ++ ((Buffer)bb).limit(orgLimit); ++ ((Buffer)to).limit(to.position()).position(to.position() - n); + return n; + } + +@@ -488,11 +488,11 @@ + long nRead = 0; + while (nRead < n) { + if (cb.remaining() >= n) { +- cb.position(cb.position() + (int) n); ++ ((Buffer)cb).position(cb.position() + (int) n); + nRead = n; + } else { + nRead += cb.remaining(); +- cb.position(cb.limit()); ++ ((Buffer)cb).position(cb.limit()); + int nb = realReadChars(); + if (nb < 0) { + break; +@@ -533,7 +533,7 @@ + } else { + if ((cb.capacity() > (2 * size)) && (cb.remaining()) < (cb.position())) { + cb.compact(); +- cb.flip(); ++ ((Buffer)cb).flip(); + } + } + readLimit = cb.position() + readAheadLimit + size; +@@ -554,7 +554,7 @@ + markPos = -1; + throw new IOException(); + } else { +- cb.position(markPos); ++ ((Buffer)cb).position(markPos); + } + } else { + clear(bb); +@@ -672,10 +672,10 @@ + + CharBuffer tmp = CharBuffer.allocate(newSize); + int oldPosition = cb.position(); +- cb.position(0); ++ ((Buffer)cb).position(0); + tmp.put(cb); +- tmp.flip(); +- tmp.position(oldPosition); ++ ((Buffer)tmp).flip(); ++ ((Buffer)tmp).position(oldPosition); + cb = tmp; + tmp = null; + } +--- apache-tomcat-9.0.30-src/java/org/apache/catalina/connector/OutputBuffer.java 2019-12-07 17:52:30.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/catalina/connector/OutputBuffer.java 2020-01-20 13:54:26.564972948 +0100 +@@ -761,10 +761,10 @@ + int limit = bb.capacity(); + int fromLimit = from.limit(); + while (from.remaining() >= limit) { +- from.limit(from.position() + limit); ++ ((Buffer)from).limit(from.position() + limit); + realWriteBytes(from.slice()); +- from.position(from.limit()); +- from.limit(fromLimit); ++ ((Buffer)from).position(from.limit()); ++ ((Buffer)from).limit(fromLimit); + } + + if (from.remaining() > 0) { +--- apache-tomcat-9.0.30-src/java/org/apache/catalina/tribes/transport/nio/NioReplicationTask.java 2019-12-07 17:52:42.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/catalina/tribes/transport/nio/NioReplicationTask.java 2020-01-20 14:05:12.048537486 +0100 +@@ -18,6 +18,7 @@ + package org.apache.catalina.tribes.transport.nio; + import java.io.IOException; + import java.net.SocketAddress; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.CancelledKeyException; + import java.nio.channels.DatagramChannel; +@@ -80,7 +81,7 @@ + buffer = ByteBuffer.allocate(size); + } + } else { +- buffer.clear(); ++ ((Buffer)buffer).clear(); + } + if (key == null) { + return; // just in case +@@ -156,30 +157,30 @@ + reader.access(); + ReadableByteChannel channel = (ReadableByteChannel) key.channel(); + int count=-1; +- buffer.clear(); // make buffer empty ++ ((Buffer)buffer).clear(); // make buffer empty + SocketAddress saddr = null; + + if (channel instanceof SocketChannel) { + // loop while data available, channel is non-blocking + while ((count = channel.read (buffer)) > 0) { +- buffer.flip(); // make buffer readable ++ ((Buffer)buffer).flip(); // make buffer readable + if ( buffer.hasArray() ) + reader.append(buffer.array(),0,count,false); + else + reader.append(buffer,count,false); +- buffer.clear(); // make buffer empty ++ ((Buffer)buffer).clear(); // make buffer empty + //do we have at least one package? + if ( reader.hasPackage() ) break; + } + } else if (channel instanceof DatagramChannel) { + DatagramChannel dchannel = (DatagramChannel)channel; + saddr = dchannel.receive(buffer); +- buffer.flip(); // make buffer readable ++ ((Buffer)buffer).flip(); // make buffer readable + if ( buffer.hasArray() ) + reader.append(buffer.array(),0,buffer.limit()-buffer.position(),false); + else + reader.append(buffer,buffer.limit()-buffer.position(),false); +- buffer.clear(); // make buffer empty ++ ((Buffer)buffer).clear(); // make buffer empty + //did we get a package + count = reader.hasPackage()?1:-1; + } +--- apache-tomcat-9.0.30-src/java/org/apache/catalina/tribes/transport/nio/NioSender.java 2019-12-07 17:52:42.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/catalina/tribes/transport/nio/NioSender.java 2020-01-20 14:08:33.229645500 +0100 +@@ -20,6 +20,7 @@ + import java.io.EOFException; + import java.io.IOException; + import java.net.InetSocketAddress; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.DatagramChannel; + import java.nio.channels.SelectionKey; +@@ -173,9 +174,9 @@ + if ( read == -1 ) throw new IOException(sm.getString("nioSender.unable.receive.ack")); + //no data read + else if ( read == 0 ) return false; +- readbuf.flip(); ++ ((Buffer)readbuf).flip(); + ackbuf.append(readbuf,read); +- readbuf.clear(); ++ ((Buffer)readbuf).clear(); + if (ackbuf.doesPackageExist() ) { + byte[] ackcmd = ackbuf.extractDataPackage(true).getBytes(); + boolean ack = Arrays.equals(ackcmd,org.apache.catalina.tribes.transport.Constants.ACK_DATA); +@@ -225,12 +226,12 @@ + if ( readbuf == null ) { + readbuf = getReadBuffer(); + } else { +- readbuf.clear(); ++ ((Buffer)readbuf).clear(); + } + if ( writebuf == null ) { + writebuf = getWriteBuffer(); + } else { +- writebuf.clear(); ++ ((Buffer)writebuf).clear(); + } + + if (isUdpBased()) { +@@ -317,8 +318,8 @@ + if ( isConnected() && readbuf == null) { + readbuf = getReadBuffer(); + } +- if ( readbuf != null ) readbuf.clear(); +- if ( writebuf != null ) writebuf.clear(); ++ if ( readbuf != null ) ((Buffer)readbuf).clear(); ++ if ( writebuf != null ) ((Buffer)writebuf).clear(); + current = null; + ackbuf.clear(); + remaining = 0; +@@ -357,7 +358,7 @@ + remaining = length; + ackbuf.clear(); + if (writebuf != null) { +- writebuf.clear(); ++ ((Buffer)writebuf).clear(); + } else { + writebuf = getBuffer(length); + } +@@ -367,7 +368,7 @@ + + // TODO use ByteBuffer.wrap to avoid copying the data. + writebuf.put(data,offset,length); +- writebuf.flip(); ++ ((Buffer)writebuf).flip(); + if (isConnected()) { + if (isUdpBased()) + dataChannel.register(getSelector(), SelectionKey.OP_WRITE, this); +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/ajp/AjpProcessor.java 2019-12-07 17:52:46.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/ajp/AjpProcessor.java 2020-01-20 09:39:10.630366487 +0100 +@@ -21,6 +21,7 @@ + import java.io.IOException; + import java.io.InterruptedIOException; + import java.net.InetAddress; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.security.NoSuchProviderException; + import java.security.cert.CertificateFactory; +@@ -1206,7 +1207,7 @@ + + responseMessage.reset(); + responseMessage.appendByte(Constants.JK_AJP13_SEND_BODY_CHUNK); +- chunk.limit(chunk.position() + thisTime); ++ ((Buffer)chunk).limit(chunk.position() + thisTime); + responseMessage.appendBytes(chunk); + responseMessage.end(); + socketWrapper.write(blocking, responseMessage.getBuffer(), 0, responseMessage.getLen()); +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/filters/BufferedInputFilter.java 2019-12-07 17:52:46.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/filters/BufferedInputFilter.java 2020-01-20 09:54:18.827537173 +0100 +@@ -18,6 +18,7 @@ + package org.apache.coyote.http11.filters; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.BufferOverflowException; + import java.nio.ByteBuffer; + import java.nio.charset.StandardCharsets; +@@ -68,7 +69,7 @@ + public void setLimit(int limit) { + if (buffered == null) { + buffered = ByteBuffer.allocate(limit); +- buffered.flip(); ++ ((Buffer)buffered).flip(); + } + } + +@@ -84,9 +85,9 @@ + // save off the Request body + try { + while (buffer.doRead(this) >= 0) { +- buffered.mark().position(buffered.limit()).limit(buffered.capacity()); ++ ((Buffer)buffered).mark().position(buffered.limit()).limit(buffered.capacity()); + buffered.put(tempRead); +- buffered.limit(buffered.position()).reset(); ++ ((Buffer)buffered).limit(buffered.position()).reset(); + tempRead = null; + } + } catch(IOException | BufferOverflowException ioe) { +@@ -121,7 +122,7 @@ + if (buffered.capacity() > 65536) { + buffered = null; + } else { +- buffered.position(0).limit(0); ++ ((Buffer)buffered).position(0).limit(0); + } + } + hasRead = false; +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2019-12-07 17:52:46.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2020-01-20 09:59:45.021458791 +0100 +@@ -18,6 +18,7 @@ + + import java.io.EOFException; + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.charset.StandardCharsets; + import java.util.Locale; +@@ -184,14 +185,14 @@ + if (readChunk != handler.getByteBuffer()) { + handler.setByteBuffer(readChunk.duplicate()); + } +- readChunk.position(readChunk.limit()); ++ ((Buffer)readChunk).position(readChunk.limit()); + } else { + result = remaining; + if (readChunk != handler.getByteBuffer()) { + handler.setByteBuffer(readChunk.duplicate()); + handler.getByteBuffer().limit(readChunk.position() + remaining); + } +- readChunk.position(readChunk.position() + remaining); ++ ((Buffer)readChunk).position(readChunk.position() + remaining); + remaining = 0; + //we need a CRLF + if ((readChunk.position() + 1) >= readChunk.limit()) { +@@ -263,7 +264,7 @@ + public void recycle() { + remaining = 0; + if (readChunk != null) { +- readChunk.position(0).limit(0); ++ ((Buffer)readChunk).position(0).limit(0); + } + endChunk = false; + needCRLFParse = false; +@@ -363,7 +364,7 @@ + + // Parsing the CRLF increments pos + if (!eol) { +- readChunk.position(readChunk.position() + 1); ++ ((Buffer)readChunk).position(readChunk.position() + 1); + } + } + +@@ -415,7 +416,7 @@ + throwIOException(sm.getString("chunkedInputFilter.invalidCrlf")); + } + +- readChunk.position(readChunk.position() + 1); ++ ((Buffer)readChunk).position(readChunk.position() + 1); + } + } + +@@ -484,7 +485,7 @@ + trailingHeaders.append(chr); + } + +- readChunk.position(readChunk.position() + 1); ++ ((Buffer)readChunk).position(readChunk.position() + 1); + + } + int colonPos = trailingHeaders.getEnd(); +@@ -513,7 +514,7 @@ + + chr = readChunk.get(readChunk.position()); + if ((chr == Constants.SP) || (chr == Constants.HT)) { +- readChunk.position(readChunk.position() + 1); ++ ((Buffer)readChunk).position(readChunk.position() + 1); + // If we swallow whitespace, make sure it counts towards the + // limit placed on trailing header size + int newlimit = trailingHeaders.getLimit() -1; +@@ -549,7 +550,7 @@ + } + + if (!eol) { +- readChunk.position(readChunk.position() + 1); ++ ((Buffer)readChunk).position(readChunk.position() + 1); + } + } + +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java 2019-12-07 17:52:46.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java 2020-01-20 10:07:29.012140554 +0100 +@@ -18,6 +18,7 @@ + + import java.io.IOException; + import java.io.OutputStreamWriter; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.charset.StandardCharsets; + import java.util.HashSet; +@@ -106,12 +107,12 @@ + + int pos = calculateChunkHeader(result); + +- chunkHeader.position(pos).limit(10); ++ ((Buffer)chunkHeader).position(pos).limit(10); + buffer.doWrite(chunkHeader); + + buffer.doWrite(chunk); + +- chunkHeader.position(8).limit(10); ++ ((Buffer)chunkHeader).position(8).limit(10); + buffer.doWrite(chunkHeader); + + return result; +@@ -171,10 +172,10 @@ + if (trailerFields == null) { + // Write end chunk + buffer.doWrite(endChunk); +- endChunk.position(0).limit(endChunk.capacity()); ++ ((Buffer)endChunk).position(0).limit(endChunk.capacity()); + } else { + buffer.doWrite(lastChunk); +- lastChunk.position(0).limit(lastChunk.capacity()); ++ ((Buffer)lastChunk).position(0).limit(lastChunk.capacity()); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); + OutputStreamWriter osw = new OutputStreamWriter(baos, StandardCharsets.ISO_8859_1); +@@ -194,7 +195,7 @@ + buffer.doWrite(ByteBuffer.wrap(baos.toByteArray())); + + buffer.doWrite(crlfChunk); +- crlfChunk.position(0).limit(crlfChunk.capacity()); ++ ((Buffer)crlfChunk).position(0).limit(crlfChunk.capacity()); + } + buffer.end(); + } +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/filters/IdentityInputFilter.java 2019-12-07 17:52:46.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/filters/IdentityInputFilter.java 2020-01-20 14:21:50.366034773 +0100 +@@ -18,6 +18,7 @@ + package org.apache.coyote.http11.filters; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.charset.StandardCharsets; + +@@ -104,7 +105,7 @@ + // The chunk is longer than the number of bytes remaining + // in the body; changing the chunk length to the number + // of bytes remaining +- handler.getByteBuffer().limit(handler.getByteBuffer().position() + (int) remaining); ++ ((Buffer)(handler.getByteBuffer())).limit(handler.getByteBuffer().position() + (int) remaining); + result = (int) remaining; + } else { + result = nRead; +@@ -116,7 +117,7 @@ + // No more bytes left to be read : return -1 and clear the + // buffer + if (handler.getByteBuffer() != null) { +- handler.getByteBuffer().position(0).limit(0); ++ ((Buffer)(handler.getByteBuffer())).position(0).limit(0); + } + result = -1; + } +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/filters/IdentityOutputFilter.java 2019-12-07 17:52:46.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/filters/IdentityOutputFilter.java 2020-01-20 14:22:41.150314386 +0100 +@@ -17,6 +17,7 @@ + package org.apache.coyote.http11.filters; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + + import org.apache.coyote.Response; +@@ -64,7 +65,7 @@ + // The chunk is longer than the number of bytes remaining + // in the body; changing the chunk length to the number + // of bytes remaining +- chunk.limit(chunk.position() + (int) remaining); ++ ((Buffer)chunk).limit(chunk.position() + (int) remaining); + result = (int) remaining; + remaining = 0; + } else { +@@ -74,8 +75,8 @@ + } else { + // No more bytes left to be written : return -1 and clear the + // buffer +- chunk.position(0); +- chunk.limit(0); ++ ((Buffer)chunk).position(0); ++ ((Buffer)chunk).limit(0); + result = -1; + } + } else { +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/filters/SavedRequestInputFilter.java 2019-12-07 17:52:47.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/filters/SavedRequestInputFilter.java 2020-01-20 09:56:16.700231571 +0100 +@@ -18,6 +18,7 @@ + package org.apache.coyote.http11.filters; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + + import org.apache.coyote.InputBuffer; +@@ -51,7 +52,7 @@ + return -1; + + ByteBuffer byteBuffer = handler.getByteBuffer(); +- byteBuffer.position(byteBuffer.limit()).limit(byteBuffer.capacity()); ++ ((Buffer)byteBuffer).position(byteBuffer.limit()).limit(byteBuffer.capacity()); + input.subtract(byteBuffer); + + return byteBuffer.remaining(); +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/Http11InputBuffer.java 2019-12-07 17:52:46.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/Http11InputBuffer.java 2020-01-20 09:49:05.393690611 +0100 +@@ -18,6 +18,7 @@ + + import java.io.EOFException; + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.charset.StandardCharsets; + import java.util.Arrays; +@@ -262,7 +263,7 @@ + activeFilters[i].recycle(); + } + +- byteBuffer.limit(0).position(0); ++ ((Buffer)byteBuffer).limit(0).position(0); + lastActiveFilter = -1; + parsingHeader = true; + swallowInput = true; +@@ -290,10 +291,10 @@ + if (byteBuffer.remaining() > 0) { + // Copy leftover bytes to the beginning of the buffer + byteBuffer.compact(); +- byteBuffer.flip(); ++ ((Buffer)byteBuffer).flip(); + } else { + // Reset position and limit to 0 +- byteBuffer.position(0).limit(0); ++ ((Buffer)byteBuffer).position(0).limit(0); + } + } + +@@ -379,7 +380,7 @@ + } + chr = byteBuffer.get(); + } while ((chr == Constants.CR) || (chr == Constants.LF)); +- byteBuffer.position(byteBuffer.position() - 1); ++ ((Buffer)byteBuffer).position(byteBuffer.position() - 1); + + parsingRequestLineStart = byteBuffer.position(); + parsingRequestLinePhase = 2; +@@ -409,7 +410,7 @@ + request.method().setBytes(byteBuffer.array(), parsingRequestLineStart, + pos - parsingRequestLineStart); + } else if (!HttpParser.isToken(chr)) { +- byteBuffer.position(byteBuffer.position() - 1); ++ ((Buffer)byteBuffer).position(byteBuffer.position() - 1); + // Avoid unknown protocol triggering an additional error + request.protocol().setString(Constants.HTTP_11); + throw new IllegalArgumentException(sm.getString("iib.invalidmethod")); +@@ -429,7 +430,7 @@ + byte chr = byteBuffer.get(); + if (!(chr == Constants.SP || chr == Constants.HT)) { + space = false; +- byteBuffer.position(byteBuffer.position() - 1); ++ ((Buffer)byteBuffer).position(byteBuffer.position() - 1); + } + } + parsingRequestLineStart = byteBuffer.position(); +@@ -498,7 +499,7 @@ + byte chr = byteBuffer.get(); + if (!(chr == Constants.SP || chr == Constants.HT)) { + space = false; +- byteBuffer.position(byteBuffer.position() - 1); ++ ((Buffer)byteBuffer).position(byteBuffer.position() - 1); + } + } + parsingRequestLineStart = byteBuffer.position(); +@@ -598,7 +599,7 @@ + + if (swallowInput && (lastActiveFilter != -1)) { + int extraBytes = (int) activeFilters[lastActiveFilter].end(); +- byteBuffer.position(byteBuffer.position() - extraBytes); ++ ((Buffer)byteBuffer).position(byteBuffer.position() - extraBytes); + } + } + +@@ -696,7 +697,7 @@ + wrapper.getSocketBufferHandler().getReadBuffer().capacity(); + if (byteBuffer == null || byteBuffer.capacity() < bufLength) { + byteBuffer = ByteBuffer.allocate(bufLength); +- byteBuffer.position(0).limit(0); ++ ((Buffer)byteBuffer).position(0).limit(0); + } + } + +@@ -721,14 +722,14 @@ + throw new IllegalArgumentException(sm.getString("iib.requestheadertoolarge.error")); + } + } else { +- byteBuffer.limit(end).position(end); ++ ((Buffer)byteBuffer).limit(end).position(end); + } + +- byteBuffer.mark(); ++ ((Buffer)byteBuffer).mark(); + if (byteBuffer.position() < byteBuffer.limit()) { +- byteBuffer.position(byteBuffer.limit()); ++ ((Buffer)byteBuffer).position(byteBuffer.limit()); + } +- byteBuffer.limit(byteBuffer.capacity()); ++ ((Buffer)byteBuffer).limit(byteBuffer.capacity()); + SocketWrapperBase socketWrapper = this.wrapper; + int nRead = -1; + if (socketWrapper != null) { +@@ -736,7 +737,7 @@ + } else { + throw new CloseNowException(sm.getString("iib.eof.error")); + } +- byteBuffer.limit(byteBuffer.position()).reset(); ++ ((Buffer)byteBuffer).limit(byteBuffer.position()).reset(); + if (nRead > 0) { + return true; + } else if (nRead == -1) { +@@ -778,7 +779,7 @@ + } else if (chr == Constants.LF) { + return HeaderParseStatus.DONE; + } else { +- byteBuffer.position(byteBuffer.position() - 1); ++ ((Buffer)byteBuffer).position(byteBuffer.position() - 1); + break; + } + +@@ -820,7 +821,7 @@ + // Non-token characters are illegal in header names + // Parsing continues so the error can be reported in context + headerData.lastSignificantChar = pos; +- byteBuffer.position(byteBuffer.position() - 1); ++ ((Buffer)byteBuffer).position(byteBuffer.position() - 1); + // skipLine() will handle the error + return skipLine(); + } +@@ -858,7 +859,7 @@ + chr = byteBuffer.get(); + if (!(chr == Constants.SP || chr == Constants.HT)) { + headerParsePos = HeaderParsePosition.HEADER_VALUE; +- byteBuffer.position(byteBuffer.position() - 1); ++ ((Buffer)byteBuffer).position(byteBuffer.position() - 1); + break; + } + } +@@ -1073,7 +1074,7 @@ + + int length = byteBuffer.remaining(); + handler.setByteBuffer(byteBuffer.duplicate()); +- byteBuffer.position(byteBuffer.limit()); ++ ((Buffer)byteBuffer).position(byteBuffer.limit()); + + return length; + } +@@ -1095,12 +1096,12 @@ + @Override + public void expand(int size) { + if (byteBuffer.capacity() >= size) { +- byteBuffer.limit(size); ++ ((Buffer)byteBuffer).limit(size); + } + ByteBuffer temp = ByteBuffer.allocate(size); + temp.put(byteBuffer); + byteBuffer = temp; +- byteBuffer.mark(); ++ ((Buffer)byteBuffer).mark(); + temp = null; + } + } +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/Http11OutputBuffer.java 2019-12-07 17:52:46.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http11/Http11OutputBuffer.java 2020-01-20 09:52:00.418721748 +0100 +@@ -17,6 +17,7 @@ + package org.apache.coyote.http11; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.util.Arrays; + +@@ -242,7 +243,7 @@ + * headers so the error response can be written. + */ + void resetHeaderBuffer() { +- headerBuffer.position(0).limit(headerBuffer.capacity()); ++ ((Buffer)headerBuffer).position(0).limit(headerBuffer.capacity()); + } + + +@@ -270,7 +271,7 @@ + // Recycle response object + response.recycle(); + // Reset pointers +- headerBuffer.position(0).limit(headerBuffer.capacity()); ++ ((Buffer)headerBuffer).position(0).limit(headerBuffer.capacity()); + lastActiveFilter = -1; + responseFinished = false; + byteCount = 0; +@@ -302,7 +303,7 @@ + + if (headerBuffer.position() > 0) { + // Sending the response header buffer +- headerBuffer.flip(); ++ ((Buffer)headerBuffer).flip(); + try { + SocketWrapperBase socketWrapper = this.socketWrapper; + if (socketWrapper != null) { +@@ -311,7 +312,7 @@ + throw new CloseNowException(sm.getString("iob.failedwrite")); + } + } finally { +- headerBuffer.position(0).limit(headerBuffer.capacity()); ++ ((Buffer)headerBuffer).position(0).limit(headerBuffer.capacity()); + } + } + } +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/HpackDecoder.java 2019-12-07 17:52:47.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/HpackDecoder.java 2020-01-20 09:18:03.823384895 +0100 +@@ -16,6 +16,7 @@ + */ + package org.apache.coyote.http2; + ++import java.nio.Buffer; + import java.nio.ByteBuffer; + + import org.apache.tomcat.util.res.StringManager; +@@ -99,10 +100,10 @@ + byte b = buffer.get(); + if ((b & 0b10000000) != 0) { + //if the first bit is set it is an indexed header field +- buffer.position(buffer.position() - 1); //unget the byte ++ ((Buffer)buffer).position(buffer.position() - 1); //unget the byte + int index = Hpack.decodeInteger(buffer, 7); //prefix is 7 + if (index == -1) { +- buffer.position(originalPos); ++ ((Buffer)buffer).position(originalPos); + return; + } else if(index == 0) { + throw new HpackException( +@@ -113,12 +114,12 @@ + //Literal Header Field with Incremental Indexing + String headerName = readHeaderName(buffer, 6); + if (headerName == null) { +- buffer.position(originalPos); ++ ((Buffer)buffer).position(originalPos); + return; + } + String headerValue = readHpackString(buffer); + if (headerValue == null) { +- buffer.position(originalPos); ++ ((Buffer)buffer).position(originalPos); + return; + } + emitHeader(headerName, headerValue); +@@ -127,12 +128,12 @@ + //Literal Header Field without Indexing + String headerName = readHeaderName(buffer, 4); + if (headerName == null) { +- buffer.position(originalPos); ++ ((Buffer)buffer).position(originalPos); + return; + } + String headerValue = readHpackString(buffer); + if (headerValue == null) { +- buffer.position(originalPos); ++ ((Buffer)buffer).position(originalPos); + return; + } + emitHeader(headerName, headerValue); +@@ -140,12 +141,12 @@ + //Literal Header Field never indexed + String headerName = readHeaderName(buffer, 4); + if (headerName == null) { +- buffer.position(originalPos); ++ ((Buffer)buffer).position(originalPos); + return; + } + String headerValue = readHpackString(buffer); + if (headerValue == null) { +- buffer.position(originalPos); ++ ((Buffer)buffer).position(originalPos); + return; + } + emitHeader(headerName, headerValue); +@@ -164,10 +165,10 @@ + if (headerCount != 0) { + throw new HpackException(sm.getString("hpackdecoder.tableSizeUpdateNotAtStart")); + } +- buffer.position(buffer.position() - 1); //unget the byte ++ ((Buffer)buffer).position(buffer.position() - 1); //unget the byte + int size = Hpack.decodeInteger(buffer, 5); + if (size == -1) { +- buffer.position(originalPos); ++ ((Buffer)buffer).position(originalPos); + return false; + } + if (size > maxMemorySizeHard) { +@@ -197,7 +198,7 @@ + } + + private String readHeaderName(ByteBuffer buffer, int prefixLength) throws HpackException { +- buffer.position(buffer.position() - 1); //unget the byte ++ ((Buffer)buffer).position(buffer.position() - 1); //unget the byte + int index = Hpack.decodeInteger(buffer, prefixLength); + if (index == -1) { + return null; +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/HPackHuffman.java 2019-12-07 17:52:47.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/HPackHuffman.java 2020-01-20 09:29:56.595310474 +0100 +@@ -16,6 +16,7 @@ + */ + package org.apache.coyote.http2; + ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.util.Arrays; + import java.util.HashSet; +@@ -483,7 +484,7 @@ + int rem = code.length; + while (rem > 0) { + if (!buffer.hasRemaining()) { +- buffer.position(start); ++ ((Buffer)buffer).position(start); + return false; + } + int remainingInByte = 8 - bytePos; +@@ -504,7 +505,7 @@ + } + if (bytePos == 8) { + if (!buffer.hasRemaining()) { +- buffer.position(start); ++ ((Buffer)buffer).position(start); + return false; + } + buffer.put(currentBufferByte); +@@ -514,14 +515,14 @@ + if (buffer.position() - start > toEncode.length()) { + //the encoded version is longer than the original + //just return false +- buffer.position(start); ++ ((Buffer)buffer).position(start); + return false; + } + } + if (bytePos > 0) { + //add the EOS bytes if we have not finished on a single byte + if (!buffer.hasRemaining()) { +- buffer.position(start); ++ ((Buffer)buffer).position(start); + return false; + } + buffer.put((byte) (currentBufferByte | ((0xFF) >> bytePos))); +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/Hpack.java 2019-12-07 17:52:47.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/Hpack.java 2020-01-20 09:26:42.590241985 +0100 +@@ -16,6 +16,7 @@ + */ + package org.apache.coyote.http2; + ++import java.nio.Buffer; + import java.nio.ByteBuffer; + + import org.apache.tomcat.util.res.StringManager; +@@ -165,7 +166,7 @@ + if (source.remaining() == 0) { + //we have run out of data + //reset +- source.position(sp); ++ ((Buffer)source).position(sp); + return -1; + } + b = source.get(); +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/Http2AsyncParser.java 2019-12-07 17:52:47.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/Http2AsyncParser.java 2020-01-20 09:36:38.985530042 +0100 +@@ -17,6 +17,7 @@ + package org.apache.coyote.http2; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.CompletionHandler; + import java.util.concurrent.TimeUnit; +@@ -103,7 +104,7 @@ + public void completed(Long result, Void attachment) { + if (streamException || error == null) { + ByteBuffer payload = buffers[2]; +- payload.flip(); ++ ((Buffer)payload).flip(); + try { + if (streamException) { + swallow(streamId, payloadSize, false, payload); +@@ -232,7 +233,7 @@ + public void completed(Long result, Void attachment) { + if (streamException || error == null) { + ByteBuffer payload = buffers[1]; +- payload.flip(); ++ ((Buffer)payload).flip(); + try { + boolean continueParsing; + do { +@@ -286,7 +287,7 @@ + if (payload.remaining() - 9 >= payloadSize) { + continueParsing = true; + // Now go over frame header +- payload.position(payload.position() + 9); ++ ((Buffer)payload).position(payload.position() + 9); + try { + validateFrame(null, frameType, streamId, flags, payloadSize); + } catch (StreamException e) { +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java 2019-12-07 17:52:47.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java 2020-01-20 09:05:00.742768450 +0100 +@@ -17,6 +17,7 @@ + package org.apache.coyote.http2; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.CompletionHandler; + import java.nio.channels.FileChannel; +@@ -216,11 +217,11 @@ + if (writeable) { + ByteUtil.set31Bits(header, 5, stream.getIdAsInt()); + int orgLimit = data.limit(); +- data.limit(data.position() + len); ++ ((Buffer)data).limit(data.position() + len); + socketWrapper.write(BlockingMode.BLOCK, protocol.getWriteTimeout(), + TimeUnit.MILLISECONDS, null, SocketWrapperBase.COMPLETE_WRITE, + applicationErrorCompletion, ByteBuffer.wrap(header), data); +- data.limit(orgLimit); ++ ((Buffer)data).limit(orgLimit); + handleAsyncException(); + } + } +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/Http2Parser.java 2019-12-07 17:52:47.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/Http2Parser.java 2020-01-20 09:13:22.253834179 +0100 +@@ -17,6 +17,7 @@ + package org.apache.coyote.http2; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.charset.StandardCharsets; + +@@ -192,9 +193,9 @@ + input.fill(true, dest, dataLength); + } else { + int oldLimit = buffer.limit(); +- buffer.limit(buffer.position() + dataLength); ++ ((Buffer)buffer).limit(buffer.position() + dataLength); + dest.put(buffer); +- buffer.limit(oldLimit); ++ ((Buffer)buffer).limit(oldLimit); + } + // Process padding before sending any notifications in case + // padding is invalid. +@@ -475,12 +476,12 @@ + input.fill(true, headerReadBuffer, toRead); + } else { + int oldLimit = buffer.limit(); +- buffer.limit(buffer.position() + toRead); ++ ((Buffer)buffer).limit(buffer.position() + toRead); + headerReadBuffer.put(buffer); +- buffer.limit(oldLimit); ++ ((Buffer)buffer).limit(oldLimit); + } + // switch to read mode +- headerReadBuffer.flip(); ++ ((Buffer)headerReadBuffer).flip(); + try { + hpackDecoder.decode(headerReadBuffer); + } catch (HpackException hpe) { +@@ -550,7 +551,7 @@ + return; + } + if (!mustBeZero && byteBuffer != null) { +- byteBuffer.position(byteBuffer.position() + len); ++ ((Buffer)byteBuffer).position(byteBuffer.position() + len); + } else { + int read = 0; + byte[] buffer = new byte[1024]; +@@ -710,7 +711,7 @@ + default boolean fill(boolean block, ByteBuffer data, int len) throws IOException { + boolean result = fill(block, data.array(), data.arrayOffset() + data.position(), len); + if (result) { +- data.position(data.position() + len); ++ ((Buffer)data).position(data.position() + len); + } + return result; + } +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/Http2UpgradeHandler.java 2019-12-07 17:52:47.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/Http2UpgradeHandler.java 2020-01-20 09:32:07.284031343 +0100 +@@ -18,6 +18,7 @@ + + import java.io.EOFException; + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.charset.StandardCharsets; + import java.util.HashSet; +@@ -762,9 +763,9 @@ + try { + socketWrapper.write(true, header, 0, header.length); + int orgLimit = data.limit(); +- data.limit(data.position() + len); ++ ((Buffer)data).limit(data.position() + len); + socketWrapper.write(true, data); +- data.limit(orgLimit); ++ ((Buffer)data).limit(orgLimit); + socketWrapper.flush(true); + } catch (IOException ioe) { + handleAppInitiatedIOException(ioe); +@@ -1830,7 +1831,7 @@ + } catch (IOException ioe) { + handleAppInitiatedIOException(ioe); + } +- payload.clear(); ++ ((Buffer)payload).clear(); + } + + @Override +--- apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/Stream.java 2019-12-07 17:52:48.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/coyote/http2/Stream.java 2020-01-20 09:25:24.129809869 +0100 +@@ -17,6 +17,7 @@ + package org.apache.coyote.http2; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.charset.StandardCharsets; + import java.security.AccessController; +@@ -850,9 +851,9 @@ + int chunkLimit = chunk.limit(); + while (chunk.remaining() > 0) { + int thisTime = Math.min(buffer.remaining(), chunk.remaining()); +- chunk.limit(chunk.position() + thisTime); ++ ((Buffer)chunk).limit(chunk.position() + thisTime); + buffer.put(chunk); +- chunk.limit(chunkLimit); ++ ((Buffer)chunk).limit(chunkLimit); + if (chunk.remaining() > 0 && !buffer.hasRemaining()) { + // Only flush if we have more data to write and the buffer + // is full +@@ -922,7 +923,7 @@ + // Buffer is empty. Nothing to do. + return false; + } +- buffer.flip(); ++ ((Buffer)buffer).flip(); + int left = buffer.remaining(); + while (left > 0) { + if (streamReservation == 0) { +@@ -953,7 +954,7 @@ + left -= connectionReservation; + } + } +- buffer.clear(); ++ ((Buffer)buffer).clear(); + return false; + } + +@@ -1014,9 +1015,9 @@ + int chunkLimit = src.limit(); + while (src.remaining() > 0) { + int thisTime = Math.min(buffer.remaining(), src.remaining()); +- src.limit(src.position() + thisTime); ++ ((Buffer)src).limit(src.position() + thisTime); + buffer.put(src); +- src.limit(chunkLimit); ++ ((Buffer)src).limit(chunkLimit); + if (flush(false, blocking)) { + return true; + } +@@ -1104,14 +1105,14 @@ + if (inBuffer.position() > 0) { + // Data is available in the inBuffer. Copy it to the + // outBuffer. +- inBuffer.flip(); ++ ((Buffer)inBuffer).flip(); + written = inBuffer.remaining(); + if (log.isDebugEnabled()) { + log.debug(sm.getString("stream.inputBuffer.copy", + Integer.toString(written))); + } + inBuffer.get(outBuffer, 0, written); +- inBuffer.clear(); ++ ((Buffer)inBuffer).clear(); + } else if (!canRead) { + return -1; + } else { +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/B2CConverter.java 2019-12-07 17:52:57.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/B2CConverter.java 2020-01-20 13:26:12.359420492 +0100 +@@ -18,6 +18,7 @@ + + import java.io.IOException; + import java.io.UnsupportedEncodingException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.CharBuffer; + import java.nio.charset.Charset; +@@ -107,7 +108,7 @@ + */ + public void recycle() { + decoder.reset(); +- leftovers.position(0); ++ ((Buffer)leftovers).position(0); + } + + /** +@@ -126,8 +127,8 @@ + bb = ByteBuffer.wrap(bc.getBuffer(), bc.getStart(), bc.getLength()); + } else { + // Initialize the byte buffer +- bb.limit(bc.getEnd()); +- bb.position(bc.getStart()); ++ ((Buffer)bb).limit(bc.getEnd()); ++ ((Buffer)bb).position(bc.getStart()); + } + if ((cb == null) || (cb.array() != cc.getBuffer())) { + // Create a new char buffer if anything changed +@@ -135,8 +136,8 @@ + cc.getBuffer().length - cc.getEnd()); + } else { + // Initialize the char buffer +- cb.limit(cc.getBuffer().length); +- cb.position(cc.getEnd()); ++ ((Buffer)cb).limit(cc.getBuffer().length); ++ ((Buffer)cb).position(cc.getEnd()); + } + CoderResult result = null; + // Parse leftover if any are present +@@ -145,16 +146,16 @@ + // Loop until one char is decoded or there is a decoder error + do { + leftovers.put(bc.subtractB()); +- leftovers.flip(); ++ ((Buffer)leftovers).flip(); + result = decoder.decode(leftovers, cb, endOfInput); +- leftovers.position(leftovers.limit()); +- leftovers.limit(leftovers.array().length); ++ ((Buffer)leftovers).position(leftovers.limit()); ++ ((Buffer)leftovers).limit(leftovers.array().length); + } while (result.isUnderflow() && (cb.position() == pos)); + if (result.isError() || result.isMalformed()) { + result.throwException(); + } +- bb.position(bc.getStart()); +- leftovers.position(0); ++ ((Buffer)bb).position(bc.getStart()); ++ ((Buffer)leftovers).position(0); + } + // Do the decoding and get the results into the byte chunk and the char + // chunk +@@ -172,8 +173,8 @@ + cc.setEnd(cb.position()); + // Put leftovers in the leftovers byte buffer + if (bc.getLength() > 0) { +- leftovers.limit(leftovers.array().length); +- leftovers.position(bc.getLength()); ++ ((Buffer)leftovers).limit(leftovers.array().length); ++ ((Buffer)leftovers).position(bc.getLength()); + bc.subtract(leftovers.array(), 0, bc.getLength()); + } + } +@@ -196,16 +197,16 @@ + bb = ByteBuffer.wrap(bc.array(), bc.arrayOffset() + bc.position(), bc.remaining()); + } else { + // Initialize the byte buffer +- bb.limit(bc.limit()); +- bb.position(bc.position()); ++ ((Buffer)bb).limit(bc.limit()); ++ ((Buffer)bb).position(bc.position()); + } + if ((cb == null) || (cb.array() != cc.array())) { + // Create a new char buffer if anything changed + cb = CharBuffer.wrap(cc.array(), cc.limit(), cc.capacity() - cc.limit()); + } else { + // Initialize the char buffer +- cb.limit(cc.capacity()); +- cb.position(cc.limit()); ++ ((Buffer)cb).limit(cc.capacity()); ++ ((Buffer)cb).position(cc.limit()); + } + CoderResult result = null; + // Parse leftover if any are present +@@ -221,16 +222,16 @@ + chr = bc.get(); + } + leftovers.put(chr); +- leftovers.flip(); ++ ((Buffer)leftovers).flip(); + result = decoder.decode(leftovers, cb, endOfInput); +- leftovers.position(leftovers.limit()); +- leftovers.limit(leftovers.array().length); ++ ((Buffer)leftovers).position(leftovers.limit()); ++ ((Buffer)leftovers).limit(leftovers.array().length); + } while (result.isUnderflow() && (cb.position() == pos)); + if (result.isError() || result.isMalformed()) { + result.throwException(); + } +- bb.position(bc.position()); +- leftovers.position(0); ++ ((Buffer)bb).position(bc.position()); ++ ((Buffer)leftovers).position(0); + } + // Do the decoding and get the results into the byte chunk and the char + // chunk +@@ -240,16 +241,16 @@ + } else if (result.isOverflow()) { + // Propagate current positions to the byte chunk and char chunk, if + // this continues the char buffer will get resized +- bc.position(bb.position()); +- cc.limit(cb.position()); ++ ((Buffer)bc).position(bb.position()); ++ ((Buffer)cc).limit(cb.position()); + } else if (result.isUnderflow()) { + // Propagate current positions to the byte chunk and char chunk +- bc.position(bb.position()); +- cc.limit(cb.position()); ++ ((Buffer)bc).position(bb.position()); ++ ((Buffer)cc).limit(cb.position()); + // Put leftovers in the leftovers byte buffer + if (bc.remaining() > 0) { +- leftovers.limit(leftovers.array().length); +- leftovers.position(bc.remaining()); ++ ((Buffer)leftovers).limit(leftovers.array().length); ++ ((Buffer)leftovers).position(bc.remaining()); + bc.get(leftovers.array(), 0, bc.remaining()); + } + } +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/ByteBufferHolder.java 2019-12-07 17:52:57.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/ByteBufferHolder.java 2020-01-20 13:26:55.607675293 +0100 +@@ -16,6 +16,7 @@ + */ + package org.apache.tomcat.util.buf; + ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.util.concurrent.atomic.AtomicBoolean; + +@@ -46,7 +47,7 @@ + + public boolean flip() { + if (flipped.compareAndSet(false, true)) { +- buf.flip(); ++ ((Buffer)buf).flip(); + return true; + } else { + return false; +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/ByteBufferUtils.java 2019-12-07 17:52:57.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/ByteBufferUtils.java 2020-01-20 13:51:31.568006546 +0100 +@@ -19,6 +19,7 @@ + import java.lang.reflect.Field; + import java.lang.reflect.InvocationTargetException; + import java.lang.reflect.Method; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + + import org.apache.juli.logging.Log; +@@ -108,7 +109,7 @@ + } + + // Copy data +- in.flip(); ++ ((Buffer)in).flip(); + out.put(in); + + if (direct) { +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/ByteChunk.java 2019-12-07 17:52:57.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/ByteChunk.java 2020-01-20 13:49:28.663327810 +0100 +@@ -19,6 +19,7 @@ + import java.io.IOException; + import java.io.ObjectInputStream; + import java.io.ObjectOutputStream; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.CharBuffer; + import java.nio.charset.Charset; +@@ -345,7 +346,7 @@ + // and avoid an extra copy + if (len == limit && end == start && out != null) { + out.realWriteBytes(from); +- from.position(from.limit()); ++ ((Buffer)from).position(from.limit()); + return; + } + // if we have limit and we're below +@@ -375,13 +376,13 @@ + int remain = len - avail; + avail = limit - end; + while (remain >= avail) { +- from.limit(from.position() + avail); ++ ((Buffer)from).limit(from.position() + avail); + out.realWriteBytes(from); +- from.position(from.limit()); ++ ((Buffer)from).position(from.limit()); + remain = remain - avail; + } + +- from.limit(fromLimit); ++ ((Buffer)from).limit(fromLimit); + from.get(buff, end, remain); + end += remain; + } +@@ -482,8 +483,8 @@ + } + int n = Math.min(to.remaining(), getLength()); + to.put(buff, start, n); +- to.limit(to.position()); +- to.position(to.position() - n); ++ ((Buffer)to).limit(to.position()); ++ ((Buffer)to).position(to.position() - n); + start += n; + return n; + } +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/C2BConverter.java 2019-12-07 17:52:57.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/C2BConverter.java 2020-01-20 14:20:33.341610658 +0100 +@@ -17,6 +17,7 @@ + package org.apache.tomcat.util.buf; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.CharBuffer; + import java.nio.charset.Charset; +@@ -51,7 +52,7 @@ + */ + public void recycle() { + encoder.reset(); +- leftovers.position(0); ++ ((Buffer)leftovers).position(0); + } + + public boolean isUndeflow() { +@@ -71,16 +72,16 @@ + bb = ByteBuffer.wrap(bc.getBuffer(), bc.getEnd(), bc.getBuffer().length - bc.getEnd()); + } else { + // Initialize the byte buffer +- bb.limit(bc.getBuffer().length); +- bb.position(bc.getEnd()); ++ ((Buffer)bb).limit(bc.getBuffer().length); ++ ((Buffer)bb).position(bc.getEnd()); + } + if ((cb == null) || (cb.array() != cc.getBuffer())) { + // Create a new char buffer if anything changed + cb = CharBuffer.wrap(cc.getBuffer(), cc.getStart(), cc.getLength()); + } else { + // Initialize the char buffer +- cb.limit(cc.getEnd()); +- cb.position(cc.getStart()); ++ ((Buffer)cb).limit(cc.getEnd()); ++ ((Buffer)cb).position(cc.getStart()); + } + CoderResult result = null; + // Parse leftover if any are present +@@ -89,16 +90,16 @@ + // Loop until one char is encoded or there is a encoder error + do { + leftovers.put((char) cc.subtract()); +- leftovers.flip(); ++ ((Buffer)leftovers).flip(); + result = encoder.encode(leftovers, bb, false); +- leftovers.position(leftovers.limit()); +- leftovers.limit(leftovers.array().length); ++ ((Buffer)leftovers).position(leftovers.limit()); ++ ((Buffer)leftovers).limit(leftovers.array().length); + } while (result.isUnderflow() && (bb.position() == pos)); + if (result.isError() || result.isMalformed()) { + result.throwException(); + } +- cb.position(cc.getStart()); +- leftovers.position(0); ++ ((Buffer)cb).position(cc.getStart()); ++ ((Buffer)leftovers).position(0); + } + // Do the decoding and get the results into the byte chunk and the char + // chunk +@@ -115,8 +116,8 @@ + cc.setOffset(cb.position()); + // Put leftovers in the leftovers char buffer + if (cc.getLength() > 0) { +- leftovers.limit(leftovers.array().length); +- leftovers.position(cc.getLength()); ++ ((Buffer)leftovers).limit(leftovers.array().length); ++ ((Buffer)leftovers).position(cc.getLength()); + cc.subtract(leftovers.array(), 0, cc.getLength()); + } + } +@@ -135,16 +136,16 @@ + bb = ByteBuffer.wrap(bc.array(), bc.limit(), bc.capacity() - bc.limit()); + } else { + // Initialize the byte buffer +- bb.limit(bc.capacity()); +- bb.position(bc.limit()); ++ ((Buffer)bb).limit(bc.capacity()); ++ ((Buffer)bb).position(bc.limit()); + } + if ((cb == null) || (cb.array() != cc.array())) { + // Create a new char buffer if anything changed + cb = CharBuffer.wrap(cc.array(), cc.arrayOffset() + cc.position(), cc.remaining()); + } else { + // Initialize the char buffer +- cb.limit(cc.limit()); +- cb.position(cc.position()); ++ ((Buffer)cb).limit(cc.limit()); ++ ((Buffer)cb).position(cc.position()); + } + CoderResult result = null; + // Parse leftover if any are present +@@ -153,16 +154,16 @@ + // Loop until one char is encoded or there is a encoder error + do { + leftovers.put(cc.get()); +- leftovers.flip(); ++ ((Buffer)leftovers).flip(); + result = encoder.encode(leftovers, bb, false); +- leftovers.position(leftovers.limit()); +- leftovers.limit(leftovers.array().length); ++ ((Buffer)leftovers).position(leftovers.limit()); ++ ((Buffer)leftovers).limit(leftovers.array().length); + } while (result.isUnderflow() && (bb.position() == pos)); + if (result.isError() || result.isMalformed()) { + result.throwException(); + } +- cb.position(cc.position()); +- leftovers.position(0); ++ ((Buffer)cb).position(cc.position()); ++ ((Buffer)leftovers).position(0); + } + // Do the decoding and get the results into the byte chunk and the char + // chunk +@@ -171,16 +172,16 @@ + result.throwException(); + } else if (result.isOverflow()) { + // Propagate current positions to the byte chunk and char chunk +- bc.limit(bb.position()); +- cc.position(cb.position()); ++ ((Buffer)bc).limit(bb.position()); ++ ((Buffer)cc).position(cb.position()); + } else if (result.isUnderflow()) { + // Propagate current positions to the byte chunk and char chunk +- bc.limit(bb.position()); +- cc.position(cb.position()); ++ ((Buffer)bc).limit(bb.position()); ++ ((Buffer)cc).position(cb.position()); + // Put leftovers in the leftovers char buffer + if (cc.remaining() > 0) { +- leftovers.limit(leftovers.array().length); +- leftovers.position(cc.remaining()); ++ ((Buffer)leftovers).limit(leftovers.array().length); ++ ((Buffer)leftovers).position(cc.remaining()); + cc.get(leftovers.array(), 0, cc.remaining()); + } + } +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/Utf8Decoder.java 2019-12-07 17:52:57.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/Utf8Decoder.java 2020-01-20 13:46:09.246215950 +0100 +@@ -16,6 +16,7 @@ + */ + package org.apache.tomcat.util.buf; + ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.CharBuffer; + import java.nio.charset.CharsetDecoder; +@@ -140,7 +141,7 @@ + } + return CoderResult.UNDERFLOW; + } finally { +- in.position(pos); ++ ((Buffer)in).position(pos); + } + } + +@@ -163,8 +164,8 @@ + // If first byte is invalid, tail will be set to -1 + int tail = remainingBytes[jchar]; + if (tail == -1) { +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(1); + } + // Additional checks to detect invalid sequences ASAP +@@ -175,72 +176,72 @@ + // First byte C2..DF, second byte 80..BF + if (jchar > 0x41 && jchar < 0x60 && + (bArr[inIndex + 1] & 0xC0) != 0x80) { +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(1); + } + // First byte E0, second byte A0..BF + if (jchar == 0x60 && (bArr[inIndex + 1] & 0xE0) != 0xA0) { +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(1); + } + // First byte E1..EC, second byte 80..BF + if (jchar > 0x60 && jchar < 0x6D && + (bArr[inIndex + 1] & 0xC0) != 0x80) { +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(1); + } + // First byte ED, second byte 80..9F + if (jchar == 0x6D && (bArr[inIndex + 1] & 0xE0) != 0x80) { +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(1); + } + // First byte EE..EF, second byte 80..BF + if (jchar > 0x6D && jchar < 0x70 && + (bArr[inIndex + 1] & 0xC0) != 0x80) { +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(1); + } + // First byte F0, second byte 90..BF + if (jchar == 0x70 && + ((bArr[inIndex + 1] & 0xFF) < 0x90 || + (bArr[inIndex + 1] & 0xFF) > 0xBF)) { +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(1); + } + // First byte F1..F3, second byte 80..BF + if (jchar > 0x70 && jchar < 0x74 && + (bArr[inIndex + 1] & 0xC0) != 0x80) { +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(1); + } + // First byte F4, second byte 80..8F + if (jchar == 0x74 && + (bArr[inIndex + 1] & 0xF0) != 0x80) { +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(1); + } + } + // Check third byte if present and expected + if (tailAvailable > 1 && tail > 1) { + if ((bArr[inIndex + 2] & 0xC0) != 0x80) { +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(2); + } + } + // Check fourth byte if present and expected + if (tailAvailable > 2 && tail > 2) { + if ((bArr[inIndex + 3] & 0xC0) != 0x80) { +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(3); + } + } +@@ -250,8 +251,8 @@ + for (int i = 0; i < tail; i++) { + int nextByte = bArr[inIndex + i + 1] & 0xFF; + if ((nextByte & 0xC0) != 0x80) { +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(1 + i); + } + jchar = (jchar << 6) + nextByte; +@@ -259,8 +260,8 @@ + jchar -= remainingNumbers[tail]; + if (jchar < lowerEncodingLimit[tail]) { + // Should have been encoded in fewer octets +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.malformedForLength(1); + } + inIndex += tail; +@@ -281,8 +282,8 @@ + // Encoded with 4 bytes. inIndex currently points + // to the final byte. Move it back to first byte. + inIndex -= 3; +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return CoderResult.OVERFLOW; + } + cArr[outIndex++] = (char) ((jchar >> 0xA) + 0xD7C0); +@@ -290,8 +291,8 @@ + outRemaining -= 2; + } + } +- in.position(inIndex - in.arrayOffset()); +- out.position(outIndex - out.arrayOffset()); ++ ((Buffer)in).position(inIndex - in.arrayOffset()); ++ ((Buffer)out).position(outIndex - out.arrayOffset()); + return (outRemaining == 0 && inIndex < inIndexLimit) ? + CoderResult.OVERFLOW : + CoderResult.UNDERFLOW; +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/Utf8Encoder.java 2019-12-07 17:52:57.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/buf/Utf8Encoder.java 2020-01-20 13:32:51.861743592 +0100 +@@ -16,6 +16,7 @@ + */ + package org.apache.tomcat.util.buf; + ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.CharBuffer; + import java.nio.charset.CharsetEncoder; +@@ -56,8 +57,8 @@ + + if (jchar <= 0x7F) { + if (outRemaining < 1) { +- in.position(x); +- out.position(outPos); ++ ((Buffer)in).position(x); ++ ((Buffer)out).position(outPos); + return CoderResult.OVERFLOW; + } + bArr[outPos++] = (byte) (jchar & 0xFF); +@@ -65,8 +66,8 @@ + } else if (jchar <= 0x7FF) { + + if (outRemaining < 2) { +- in.position(x); +- out.position(outPos); ++ ((Buffer)in).position(x); ++ ((Buffer)out).position(outPos); + return CoderResult.OVERFLOW; + } + bArr[outPos++] = (byte) (0xC0 + ((jchar >> 6) & 0x1F)); +@@ -77,21 +78,21 @@ + + // in has to have one byte more. + if (limit <= x + 1) { +- in.position(x); +- out.position(outPos); ++ ((Buffer)in).position(x); ++ ((Buffer)out).position(outPos); + return CoderResult.UNDERFLOW; + } + + if (outRemaining < 4) { +- in.position(x); +- out.position(outPos); ++ ((Buffer)in).position(x); ++ ((Buffer)out).position(outPos); + return CoderResult.OVERFLOW; + } + + // The surrogate pair starts with a low-surrogate. + if (jchar >= 0xDC00) { +- in.position(x); +- out.position(outPos); ++ ((Buffer)in).position(x); ++ ((Buffer)out).position(outPos); + return CoderResult.malformedForLength(1); + } + +@@ -99,8 +100,8 @@ + + // The surrogate pair ends with a high-surrogate. + if (jchar2 < 0xDC00) { +- in.position(x); +- out.position(outPos); ++ ((Buffer)in).position(x); ++ ((Buffer)out).position(outPos); + return CoderResult.malformedForLength(1); + } + +@@ -121,8 +122,8 @@ + } else { + + if (outRemaining < 3) { +- in.position(x); +- out.position(outPos); ++ ((Buffer)in).position(x); ++ ((Buffer)out).position(outPos); + return CoderResult.OVERFLOW; + } + bArr[outPos++] = (byte) (0xE0 + ((jchar >> 12) & 0x0F)); +@@ -131,8 +132,8 @@ + outRemaining -= 3; + } + if (outRemaining == 0) { +- in.position(x + 1); +- out.position(outPos); ++ ((Buffer)in).position(x + 1); ++ ((Buffer)out).position(outPos); + // If both input and output are exhausted, return UNDERFLOW + if (x + 1 == limit) { + return CoderResult.UNDERFLOW; +@@ -143,8 +144,8 @@ + + } + if (rem != 0) { +- in.position(x); +- out.position(outPos); ++ ((Buffer)in).position(x); ++ ((Buffer)out).position(outPos); + } + return CoderResult.UNDERFLOW; + } +@@ -228,7 +229,7 @@ + pos++; + } + } finally { +- in.position(pos); ++ ((Buffer)in).position(pos); + } + return CoderResult.UNDERFLOW; + } +Only in apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/http/parser: tomcat-9.0.30-java8compat.patch +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/AprEndpoint.java 2019-12-07 17:53:02.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/AprEndpoint.java 2020-01-20 13:09:09.049553953 +0100 +@@ -20,6 +20,7 @@ + import java.io.IOException; + import java.net.InetSocketAddress; + import java.net.SocketTimeoutException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.CompletionHandler; + import java.nio.charset.StandardCharsets; +@@ -2040,7 +2041,7 @@ + // SSL and app buffer size settings with NIO & NIO2. + if (endpoint.isSSLEnabled()) { + sslOutputBuffer = ByteBuffer.allocateDirect(SSL_OUTPUT_BUFFER_SIZE); +- sslOutputBuffer.position(SSL_OUTPUT_BUFFER_SIZE); ++ ((Buffer)sslOutputBuffer).position(SSL_OUTPUT_BUFFER_SIZE); + } else { + sslOutputBuffer = null; + } +@@ -2102,7 +2103,7 @@ + // The socket read buffer capacity is socket.appReadBufSize + int limit = socketBufferHandler.getReadBuffer().capacity(); + if (to.isDirect() && to.remaining() >= limit) { +- to.limit(to.position() + limit); ++ ((Buffer)to).limit(to.position() + limit); + nRead = fillReadBuffer(block, to); + if (log.isDebugEnabled()) { + log.debug("Socket: [" + this + "], Read direct from socket: [" + nRead + "]"); +@@ -2181,7 +2182,7 @@ + } + + if (result > 0) { +- to.position(to.position() + result); ++ ((Buffer)to).position(to.position() + result); + return result; + } else if (result == 0 || -result == Status.EAGAIN) { + return 0; +@@ -2305,9 +2306,9 @@ + if (getEndpoint().isSSLEnabled()) { + if (sslOutputBuffer.remaining() == 0) { + // Buffer was fully written last time around +- sslOutputBuffer.clear(); ++ ((Buffer)sslOutputBuffer).clear(); + transfer(from, sslOutputBuffer); +- sslOutputBuffer.flip(); ++ ((Buffer)sslOutputBuffer).flip(); + } else { + // Buffer still has data from previous attempt to write + // APR + SSL requires that exactly the same parameters are +@@ -2316,13 +2317,13 @@ + thisTime = Socket.sendb(getSocket().longValue(), sslOutputBuffer, + sslOutputBuffer.position(), sslOutputBuffer.limit()); + if (thisTime > 0) { +- sslOutputBuffer.position(sslOutputBuffer.position() + thisTime); ++ ((Buffer)sslOutputBuffer).position(sslOutputBuffer.position() + thisTime); + } + } else { + thisTime = Socket.sendb(getSocket().longValue(), from, from.position(), + from.remaining()); + if (thisTime > 0) { +- from.position(from.position() + thisTime); ++ ((Buffer)from).position(from.position() + thisTime); + } + } + if (Status.APR_STATUS_IS_EAGAIN(-thisTime)) { +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/Nio2Endpoint.java 2019-12-07 17:53:02.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/Nio2Endpoint.java 2020-01-20 14:24:28.286904277 +0100 +@@ -22,6 +22,7 @@ + import java.net.InetSocketAddress; + import java.net.SocketAddress; + import java.net.SocketTimeoutException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.AsynchronousChannelGroup; + import java.nio.channels.AsynchronousCloseException; +@@ -541,7 +542,7 @@ + if (nRead > 0) { + getSocket().getBufHandler().configureWriteBufferForRead(); + if (attachment.length < buffer.remaining()) { +- buffer.limit(buffer.limit() - buffer.remaining() + (int) attachment.length); ++ ((Buffer)buffer).limit(buffer.limit() - buffer.remaining() + (int) attachment.length); + } + attachment.length -= nRead; + } else { +@@ -895,7 +896,7 @@ + // The socket read buffer capacity is socket.appReadBufSize + int limit = socketBufferHandler.getReadBuffer().capacity(); + if (block && to.remaining() >= limit) { +- to.limit(to.position() + limit); ++ ((Buffer)to).limit(to.position() + limit); + nRead = fillReadBuffer(block, to); + if (log.isDebugEnabled()) { + log.debug("Socket: [" + this + "], Read direct from socket: [" + nRead + "]"); +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/NioEndpoint.java 2019-12-07 17:53:02.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/NioEndpoint.java 2020-01-20 13:03:47.719842418 +0100 +@@ -23,6 +23,7 @@ + import java.net.InetAddress; + import java.net.InetSocketAddress; + import java.net.SocketTimeoutException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.CancelledKeyException; + import java.nio.channels.Channel; +@@ -1139,7 +1140,7 @@ + // The socket read buffer capacity is socket.appReadBufSize + int limit = socketBufferHandler.getReadBuffer().capacity(); + if (to.remaining() >= limit) { +- to.limit(to.position() + limit); ++ ((Buffer)to).limit(to.position() + limit); + nRead = fillReadBuffer(block, to); + if (log.isDebugEnabled()) { + log.debug("Socket: [" + this + "], Read direct from socket: [" + nRead + "]"); +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java 2019-12-07 17:53:03.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java 2020-01-20 11:28:33.194522708 +0100 +@@ -16,6 +16,7 @@ + */ + package org.apache.tomcat.util.net.openssl; + ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.ReadOnlyBufferException; + import java.security.Principal; +@@ -40,7 +41,7 @@ + + import org.apache.juli.logging.Log; + import org.apache.juli.logging.LogFactory; +-import org.apache.tomcat.jni.Buffer; ++// import org.apache.tomcat.jni.Buffer; + import org.apache.tomcat.jni.Pool; + import org.apache.tomcat.jni.SSL; + import org.apache.tomcat.jni.SSLContext; +@@ -130,7 +131,7 @@ + + private static final String INVALID_CIPHER = "SSL_NULL_WITH_NULL_NULL"; + +- private static final long EMPTY_ADDR = Buffer.address(ByteBuffer.allocate(0)); ++ private static final long EMPTY_ADDR = org.apache.tomcat.jni.Buffer.address(ByteBuffer.allocate(0)); + + // OpenSSL state + private long ssl; +@@ -242,10 +243,10 @@ + final int sslWrote; + + if (src.isDirect()) { +- final long addr = Buffer.address(src) + pos; ++ final long addr = org.apache.tomcat.jni.Buffer.address(src) + pos; + sslWrote = SSL.writeToSSL(ssl, addr, len); + if (sslWrote >= 0) { +- src.position(pos + sslWrote); ++ ((Buffer)src).position(pos + sslWrote); + return sslWrote; + } + } else { +@@ -253,17 +254,17 @@ + try { + final long addr = memoryAddress(buf); + +- src.limit(pos + len); ++ ((Buffer)src).limit(pos + len); + + buf.put(src); +- src.limit(limit); ++ ((Buffer)src).limit(limit); + + sslWrote = SSL.writeToSSL(ssl, addr, len); + if (sslWrote >= 0) { +- src.position(pos + sslWrote); ++ ((Buffer)src).position(pos + sslWrote); + return sslWrote; + } else { +- src.position(pos); ++ ((Buffer)src).position(pos); + } + } finally { + buf.clear(); +@@ -282,10 +283,10 @@ + final int pos = src.position(); + final int len = src.remaining(); + if (src.isDirect()) { +- final long addr = Buffer.address(src) + pos; ++ final long addr = org.apache.tomcat.jni.Buffer.address(src) + pos; + final int netWrote = SSL.writeToBIO(networkBIO, addr, len); + if (netWrote >= 0) { +- src.position(pos + netWrote); ++ ((Buffer)src).position(pos + netWrote); + return netWrote; + } + } else { +@@ -297,10 +298,10 @@ + + final int netWrote = SSL.writeToBIO(networkBIO, addr, len); + if (netWrote >= 0) { +- src.position(pos + netWrote); ++ ((Buffer)src).position(pos + netWrote); + return netWrote; + } else { +- src.position(pos); ++ ((Buffer)src).position(pos); + } + } finally { + buf.clear(); +@@ -317,11 +318,11 @@ + private static int readPlaintextData(final long ssl, final ByteBuffer dst) { + if (dst.isDirect()) { + final int pos = dst.position(); +- final long addr = Buffer.address(dst) + pos; ++ final long addr = org.apache.tomcat.jni.Buffer.address(dst) + pos; + final int len = dst.limit() - pos; + final int sslRead = SSL.readFromSSL(ssl, addr, len); + if (sslRead > 0) { +- dst.position(pos + sslRead); ++ ((Buffer)dst).position(pos + sslRead); + return sslRead; + } + } else { +@@ -335,9 +336,9 @@ + final int sslRead = SSL.readFromSSL(ssl, addr, len); + if (sslRead > 0) { + buf.limit(sslRead); +- dst.limit(pos + sslRead); ++ ((Buffer)dst).limit(pos + sslRead); + dst.put(buf); +- dst.limit(limit); ++ ((Buffer)dst).limit(limit); + return sslRead; + } + } finally { +@@ -355,10 +356,10 @@ + private static int readEncryptedData(final long networkBIO, final ByteBuffer dst, final int pending) { + if (dst.isDirect() && dst.remaining() >= pending) { + final int pos = dst.position(); +- final long addr = Buffer.address(dst) + pos; ++ final long addr = org.apache.tomcat.jni.Buffer.address(dst) + pos; + final int bioRead = SSL.readFromBIO(networkBIO, addr, pending); + if (bioRead > 0) { +- dst.position(pos + bioRead); ++ ((Buffer)dst).position(pos + bioRead); + return bioRead; + } + } else { +@@ -370,9 +371,9 @@ + if (bioRead > 0) { + buf.limit(bioRead); + int oldLimit = dst.limit(); +- dst.limit(dst.position() + bioRead); ++ ((Buffer)dst).limit(dst.position() + bioRead); + dst.put(buf); +- dst.limit(oldLimit); ++ ((Buffer)dst).limit(oldLimit); + return bioRead; + } + } finally { +@@ -963,7 +964,7 @@ + + + private static long memoryAddress(ByteBuffer buf) { +- return Buffer.address(buf); ++ return org.apache.tomcat.jni.Buffer.address(buf); + } + + private SSLEngineResult.Status getEngineStatus() { +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/SecureNio2Channel.java 2019-12-07 17:53:02.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/SecureNio2Channel.java 2020-01-20 13:02:26.163408028 +0100 +@@ -18,6 +18,7 @@ + + import java.io.EOFException; + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.AsynchronousSocketChannel; + import java.nio.channels.CompletionHandler; +@@ -133,7 +134,7 @@ + unwrapBeforeRead = true; + closed = false; + closing = false; +- netInBuffer.clear(); ++ ((Buffer)netInBuffer).clear(); + } + + @Override +@@ -323,7 +324,7 @@ + } else if (handshake.getStatus() == Status.BUFFER_UNDERFLOW) { + if (netInBuffer.position() == netInBuffer.limit()) { + //clear the buffer if we have emptied it out on data +- netInBuffer.clear(); ++ ((Buffer)netInBuffer).clear(); + } + //read more data + if (async) { +@@ -418,9 +419,9 @@ + clientRequestedCiphers = Collections.emptyList(); + break; + case NON_SECURE: +- netOutBuffer.clear(); ++ ((Buffer)netOutBuffer).clear(); + netOutBuffer.put(TLSClientHelloExtractor.USE_TLS_RESPONSE); +- netOutBuffer.flip(); ++ ((Buffer)netOutBuffer).flip(); + flush(); + throw new IOException(sm.getString("channel.nio.ssl.foundHttp")); + } +@@ -444,8 +445,8 @@ + netOutBuffer = ByteBufferUtils.expand(netOutBuffer, sslEngine.getSession().getPacketBufferSize()); + + // Set limit and position to expected values +- netOutBuffer.position(0); +- netOutBuffer.limit(0); ++ ((Buffer)netOutBuffer).position(0); ++ ((Buffer)netOutBuffer).limit(0); + + // Initiate handshake + sslEngine.beginHandshake(); +@@ -469,10 +470,10 @@ + if (!getBufHandler().isReadBufferEmpty()) throw new IOException(sm.getString("channel.nio.ssl.appInputNotEmpty")); + if (!getBufHandler().isWriteBufferEmpty()) throw new IOException(sm.getString("channel.nio.ssl.appOutputNotEmpty")); + +- netOutBuffer.position(0); +- netOutBuffer.limit(0); +- netInBuffer.position(0); +- netInBuffer.limit(0); ++ ((Buffer)netOutBuffer).position(0); ++ ((Buffer)netOutBuffer).limit(0); ++ ((Buffer)netInBuffer).position(0); ++ ((Buffer)netInBuffer).limit(0); + getBufHandler().reset(); + + handshakeComplete = false; +@@ -521,12 +522,12 @@ + protected SSLEngineResult handshakeWrap() throws IOException { + //this should never be called with a network buffer that contains data + //so we can clear it here. +- netOutBuffer.clear(); ++ ((Buffer)netOutBuffer).clear(); + //perform the wrap + getBufHandler().configureWriteBufferForRead(); + SSLEngineResult result = sslEngine.wrap(getBufHandler().getWriteBuffer(), netOutBuffer); + //prepare the results to be written +- netOutBuffer.flip(); ++ ((Buffer)netOutBuffer).flip(); + //set the status + handshakeStatus = result.getHandshakeStatus(); + return result; +@@ -543,7 +544,7 @@ + //loop while we can perform pure SSLEngine data + do { + //prepare the buffer with the incoming data +- netInBuffer.flip(); ++ ((Buffer)netInBuffer).flip(); + //call unwrap + getBufHandler().configureReadBufferForWrite(); + result = sslEngine.unwrap(netInBuffer, getBufHandler().getReadBuffer()); +@@ -601,7 +602,7 @@ + throw new IOException(sm.getString("channel.nio.ssl.pendingWriteDuringClose"), e); + } + //prep the buffer for the close message +- netOutBuffer.clear(); ++ ((Buffer)netOutBuffer).clear(); + //perform the close, since we called sslEngine.closeOutbound + SSLEngineResult handshake = sslEngine.wrap(getEmptyBuf(), netOutBuffer); + //we should be in a close state +@@ -609,7 +610,7 @@ + throw new IOException(sm.getString("channel.nio.ssl.invalidCloseState")); + } + //prepare the buffer for writing +- netOutBuffer.flip(); ++ ((Buffer)netOutBuffer).flip(); + //if there is data to be written + try { + if (timeout > 0) { +@@ -711,7 +712,7 @@ + SSLEngineResult unwrap; + do { + //prepare the buffer +- netInBuffer.flip(); ++ ((Buffer)netInBuffer).flip(); + //unwrap the data + try { + unwrap = sslEngine.unwrap(netInBuffer, dst); +@@ -854,10 +855,10 @@ + protected void wrap() { + try { + if (!netOutBuffer.hasRemaining()) { +- netOutBuffer.clear(); ++ ((Buffer)netOutBuffer).clear(); + SSLEngineResult result = sslEngine.wrap(src, netOutBuffer); + written = result.bytesConsumed(); +- netOutBuffer.flip(); ++ ((Buffer)netOutBuffer).flip(); + if (result.getStatus() == Status.OK) { + if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) + tasks(); +@@ -909,7 +910,7 @@ + SSLEngineResult unwrap; + do { + //prepare the buffer +- netInBuffer.flip(); ++ ((Buffer)netInBuffer).flip(); + //unwrap the data + unwrap = sslEngine.unwrap(netInBuffer, dst2); + //compact the buffer +@@ -1019,7 +1020,7 @@ + } + processOverflow = false; + //prepare the buffer +- netInBuffer.flip(); ++ ((Buffer)netInBuffer).flip(); + //unwrap the data + unwrap = sslEngine.unwrap(netInBuffer, dsts2, offset, length2); + //compact the buffer +@@ -1138,11 +1139,11 @@ + } + try { + // Prepare the output buffer +- netOutBuffer.clear(); ++ ((Buffer)netOutBuffer).clear(); + // Wrap the source data into the internal buffer + SSLEngineResult result = sslEngine.wrap(src, netOutBuffer); + final int written = result.bytesConsumed(); +- netOutBuffer.flip(); ++ ((Buffer)netOutBuffer).flip(); + if (result.getStatus() == Status.OK) { + if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { + tasks(); +@@ -1192,11 +1193,11 @@ + } + try { + // Prepare the output buffer +- netOutBuffer.clear(); ++ ((Buffer)netOutBuffer).clear(); + // Wrap the source data into the internal buffer + SSLEngineResult result = sslEngine.wrap(srcs, offset, length, netOutBuffer); + final int written = result.bytesConsumed(); +- netOutBuffer.flip(); ++ ((Buffer)netOutBuffer).flip(); + if (result.getStatus() == Status.OK) { + if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { + tasks(); +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/SecureNioChannel.java 2019-12-07 17:53:02.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/SecureNioChannel.java 2020-01-20 11:12:08.929715874 +0100 +@@ -19,6 +19,7 @@ + import java.io.EOFException; + import java.io.IOException; + import java.net.SocketTimeoutException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.SelectionKey; + import java.nio.channels.Selector; +@@ -95,7 +96,7 @@ + handshakeComplete = false; + closed = false; + closing = false; +- netInBuffer.clear(); ++ ((Buffer)netInBuffer).clear(); + } + + @Override +@@ -315,9 +316,9 @@ + clientRequestedCiphers = Collections.emptyList(); + break; + case NON_SECURE: +- netOutBuffer.clear(); ++ ((Buffer)netOutBuffer).clear(); + netOutBuffer.put(TLSClientHelloExtractor.USE_TLS_RESPONSE); +- netOutBuffer.flip(); ++ ((Buffer)netOutBuffer).flip(); + flushOutbound(); + throw new IOException(sm.getString("channel.nio.ssl.foundHttp")); + } +@@ -341,8 +342,8 @@ + netOutBuffer = ByteBufferUtils.expand(netOutBuffer, sslEngine.getSession().getPacketBufferSize()); + + // Set limit and position to expected values +- netOutBuffer.position(0); +- netOutBuffer.limit(0); ++ ((Buffer)netOutBuffer).position(0); ++ ((Buffer)netOutBuffer).limit(0); + + // Initiate handshake + sslEngine.beginHandshake(); +@@ -454,12 +455,12 @@ + protected SSLEngineResult handshakeWrap(boolean doWrite) throws IOException { + //this should never be called with a network buffer that contains data + //so we can clear it here. +- netOutBuffer.clear(); ++ ((Buffer)netOutBuffer).clear(); + //perform the wrap + getBufHandler().configureWriteBufferForRead(); + SSLEngineResult result = sslEngine.wrap(getBufHandler().getWriteBuffer(), netOutBuffer); + //prepare the results to be written +- netOutBuffer.flip(); ++ ((Buffer)netOutBuffer).flip(); + //set the status + handshakeStatus = result.getHandshakeStatus(); + //optimization, if we do have a writable channel, write it now +@@ -479,7 +480,7 @@ + + if (netInBuffer.position() == netInBuffer.limit()) { + //clear the buffer if we have emptied it out on data +- netInBuffer.clear(); ++ ((Buffer)netInBuffer).clear(); + } + if (doread) { + //if we have data to read, read it +@@ -493,7 +494,7 @@ + //loop while we can perform pure SSLEngine data + do { + //prepare the buffer with the incoming data +- netInBuffer.flip(); ++ ((Buffer)netInBuffer).flip(); + //call unwrap + getBufHandler().configureReadBufferForWrite(); + result = sslEngine.unwrap(netInBuffer, getBufHandler().getReadBuffer()); +@@ -537,7 +538,7 @@ + throw new IOException(sm.getString("channel.nio.ssl.remainingDataDuringClose")); + } + //prep the buffer for the close message +- netOutBuffer.clear(); ++ ((Buffer)netOutBuffer).clear(); + //perform the close, since we called sslEngine.closeOutbound + SSLEngineResult handshake = sslEngine.wrap(getEmptyBuf(), netOutBuffer); + //we should be in a close state +@@ -545,7 +546,7 @@ + throw new IOException(sm.getString("channel.nio.ssl.invalidCloseState")); + } + //prepare the buffer for writing +- netOutBuffer.flip(); ++ ((Buffer)netOutBuffer).flip(); + //if there is data to be written + flush(netOutBuffer); + +@@ -612,7 +613,7 @@ + SSLEngineResult unwrap; + do { + //prepare the buffer +- netInBuffer.flip(); ++ ((Buffer)netInBuffer).flip(); + //unwrap the data + unwrap = sslEngine.unwrap(netInBuffer, dst); + //compact the buffer +@@ -691,7 +692,7 @@ + } + processOverflow = false; + //prepare the buffer +- netInBuffer.flip(); ++ ((Buffer)netInBuffer).flip(); + //unwrap the data + unwrap = sslEngine.unwrap(netInBuffer, dsts, offset, length); + //compact the buffer +@@ -798,12 +799,12 @@ + } + + // The data buffer is empty, we can reuse the entire buffer. +- netOutBuffer.clear(); ++ ((Buffer)netOutBuffer).clear(); + + SSLEngineResult result = sslEngine.wrap(src, netOutBuffer); + // The number of bytes written + int written = result.bytesConsumed(); +- netOutBuffer.flip(); ++ ((Buffer)netOutBuffer).flip(); + + if (result.getStatus() == Status.OK) { + if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { +@@ -835,12 +836,12 @@ + } + + // The data buffer is empty, we can reuse the entire buffer. +- netOutBuffer.clear(); ++ ((Buffer)netOutBuffer).clear(); + + SSLEngineResult result = sslEngine.wrap(srcs, offset, length, netOutBuffer); + // The number of bytes written + int written = result.bytesConsumed(); +- netOutBuffer.flip(); ++ ((Buffer)netOutBuffer).flip(); + + if (result.getStatus() == Status.OK) { + if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) tasks(); +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/SocketBufferHandler.java 2019-12-07 17:53:02.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/SocketBufferHandler.java 2020-01-20 12:54:39.092912909 +0100 +@@ -16,6 +16,7 @@ + */ + package org.apache.tomcat.util.net; + ++import java.nio.Buffer; + import java.nio.ByteBuffer; + + import org.apache.tomcat.util.buf.ByteBufferUtils; +@@ -66,13 +67,13 @@ + // Switching to write + int remaining = readBuffer.remaining(); + if (remaining == 0) { +- readBuffer.clear(); ++ ((Buffer)readBuffer).clear(); + } else { + readBuffer.compact(); + } + } else { + // Switching to read +- readBuffer.flip(); ++ ((Buffer)readBuffer).flip(); + } + this.readBufferConfiguredForWrite = readBufferConFiguredForWrite; + } +@@ -110,15 +111,15 @@ + // Switching to write + int remaining = writeBuffer.remaining(); + if (remaining == 0) { +- writeBuffer.clear(); ++ ((Buffer)writeBuffer).clear(); + } else { + writeBuffer.compact(); +- writeBuffer.position(remaining); +- writeBuffer.limit(writeBuffer.capacity()); ++ ((Buffer)writeBuffer).position(remaining); ++ ((Buffer)writeBuffer).limit(writeBuffer.capacity()); + } + } else { + // Switching to read +- writeBuffer.flip(); ++ ((Buffer)writeBuffer).flip(); + } + this.writeBufferConfiguredForWrite = writeBufferConfiguredForWrite; + } +@@ -149,9 +150,9 @@ + + + public void reset() { +- readBuffer.clear(); ++ ((Buffer)readBuffer).clear(); + readBufferConfiguredForWrite = true; +- writeBuffer.clear(); ++ ((Buffer)writeBuffer).clear(); + writeBufferConfiguredForWrite = true; + } + +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/SocketWrapperBase.java 2019-12-07 17:53:02.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/SocketWrapperBase.java 2020-01-20 11:02:14.534448210 +0100 +@@ -19,6 +19,7 @@ + import java.io.EOFException; + import java.io.IOException; + import java.net.SocketTimeoutException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.CompletionHandler; + import java.nio.channels.InterruptedByTimeoutException; +@@ -1468,9 +1469,9 @@ + int max = Math.min(from.remaining(), to.remaining()); + if (max > 0) { + int fromLimit = from.limit(); +- from.limit(from.position() + max); ++ ((Buffer)from).limit(from.position() + max); + to.put(from); +- from.limit(fromLimit); ++ ((Buffer)from).limit(fromLimit); + } + return max; + } +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java 2019-12-07 17:53:02.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java 2020-01-20 11:07:24.084149952 +0100 +@@ -17,6 +17,7 @@ + package org.apache.tomcat.util.net; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.BufferUnderflowException; + import java.nio.ByteBuffer; + import java.nio.charset.StandardCharsets; +@@ -76,7 +77,7 @@ + String sniValue = null; + try { + // Switch to read mode. +- netInBuffer.flip(); ++ ((Buffer)netInBuffer).flip(); + + // A complete TLS record header is required before we can figure out + // how many bytes there are in the record. +@@ -164,8 +165,8 @@ + this.clientRequestedApplicationProtocols = clientRequestedApplicationProtocols; + this.sniValue = sniValue; + // Whatever happens, return the buffer to its original state +- netInBuffer.limit(limit); +- netInBuffer.position(pos); ++ ((Buffer)netInBuffer).limit(limit); ++ ((Buffer)netInBuffer).position(pos); + } + } + +@@ -215,7 +216,7 @@ + + private static boolean isAvailable(ByteBuffer bb, int size) { + if (bb.remaining() < size) { +- bb.position(bb.limit()); ++ ((Buffer)bb).position(bb.limit()); + return false; + } + return true; +@@ -243,7 +244,7 @@ + // the buffer contains a correctly formatted HTTP request line. + // The method, target and protocol are not validated. + byte chr = 0; +- bb.position(0); ++ ((Buffer)bb).position(0); + + // Skip blank lines + do { +@@ -324,7 +325,7 @@ + + + private static void skipBytes(ByteBuffer bb, int size) { +- bb.position(bb.position() + size); ++ ((Buffer)bb).position(bb.position() + size); + } + + +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/WriteBuffer.java 2019-12-07 17:53:02.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/util/net/WriteBuffer.java 2020-01-20 14:27:27.007888388 +0100 +@@ -17,6 +17,7 @@ + package org.apache.tomcat.util.net; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.util.ArrayList; + import java.util.Iterator; +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/AsyncChannelWrapperSecure.java 2019-12-07 17:53:04.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/AsyncChannelWrapperSecure.java 2020-01-20 10:17:25.199489032 +0100 +@@ -18,6 +18,7 @@ + + import java.io.EOFException; + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.AsynchronousSocketChannel; + import java.nio.channels.CompletionHandler; +@@ -189,7 +190,7 @@ + for (int i = offset; i < offset + length; i++) { + ByteBuffer src = srcs[i]; + while (src.hasRemaining()) { +- socketWriteBuffer.clear(); ++ ((Buffer)socketWriteBuffer).clear(); + + // Encrypt the data + SSLEngineResult r = sslEngine.wrap(src, socketWriteBuffer); +@@ -215,7 +216,7 @@ + } + } + +- socketWriteBuffer.flip(); ++ ((Buffer)socketWriteBuffer).flip(); + + // Do the write + int toWrite = r.bytesProduced(); +@@ -272,7 +273,7 @@ + } + } + +- socketReadBuffer.flip(); ++ ((Buffer)socketReadBuffer).flip(); + + if (socketReadBuffer.hasRemaining()) { + // Decrypt the data in the buffer +@@ -358,7 +359,7 @@ + try { + sslEngine.beginHandshake(); + // So the first compact does the right thing +- socketReadBuffer.position(socketReadBuffer.limit()); ++ ((Buffer)socketReadBuffer).position(socketReadBuffer.limit()); + + handshakeStatus = sslEngine.getHandshakeStatus(); + resultStatus = Status.OK; +@@ -368,11 +369,11 @@ + while(handshaking) { + switch (handshakeStatus) { + case NEED_WRAP: { +- socketWriteBuffer.clear(); ++ ((Buffer)socketWriteBuffer).clear(); + SSLEngineResult r = + sslEngine.wrap(DUMMY, socketWriteBuffer); + checkResult(r, true); +- socketWriteBuffer.flip(); ++ ((Buffer)socketWriteBuffer).flip(); + Future fWrite = + socketChannel.write(socketWriteBuffer); + fWrite.get(); +@@ -386,7 +387,7 @@ + socketChannel.read(socketReadBuffer); + fRead.get(); + } +- socketReadBuffer.flip(); ++ ((Buffer)socketReadBuffer).flip(); + SSLEngineResult r = + sslEngine.unwrap(socketReadBuffer, DUMMY); + checkResult(r, false); +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/PerMessageDeflate.java 2019-12-07 17:53:05.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/PerMessageDeflate.java 2020-01-20 10:22:12.705103815 +0100 +@@ -17,6 +17,7 @@ + package org.apache.tomcat.websocket; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.util.ArrayList; + import java.util.List; +@@ -207,11 +208,11 @@ + } catch (NullPointerException e) { + throw new IOException(sm.getString("perMessageDeflate.alreadyClosed"), e); + } +- dest.position(dest.position() + written); ++ ((Buffer)dest).position(dest.position() + written); + + if (inflater.needsInput() && !usedEomBytes ) { + if (dest.hasRemaining()) { +- readBuffer.clear(); ++ ((Buffer)readBuffer).clear(); + TransformationResult nextResult = + next.getMoreData(opCode, fin, (rsv ^ RSV_BITMASK), readBuffer); + inflater.setInput( +@@ -355,7 +356,7 @@ + int written = deflater.deflate(compressedPayload.array(), + compressedPayload.arrayOffset() + compressedPayload.position(), + compressedPayload.remaining(), flush); +- compressedPayload.position(compressedPayload.position() + written); ++ ((Buffer)compressedPayload).position(compressedPayload.position() + written); + } catch (NullPointerException e) { + throw new IOException(sm.getString("perMessageDeflate.alreadyClosed"), e); + } +@@ -375,7 +376,7 @@ + writeBuffer = ByteBuffer.allocate(Constants.DEFAULT_BUFFER_SIZE); + + // Flip the compressed payload ready for writing +- compressedPayload.flip(); ++ ((Buffer)compressedPayload).flip(); + + boolean fin = uncompressedPart.isFin(); + boolean full = compressedPayload.limit() == compressedPayload.capacity(); +@@ -384,7 +385,7 @@ + + if (fin && !full && needsInput) { + // End of compressed message. Drop EOM bytes and output. +- compressedPayload.limit(compressedPayload.limit() - EOM_BYTES.length); ++ ((Buffer)compressedPayload).limit(compressedPayload.limit() - EOM_BYTES.length); + compressedPart = new MessagePart(true, getRsv(uncompressedPart), + opCode, compressedPayload, uncompressedIntermediateHandler, + uncompressedIntermediateHandler, blockingWriteTimeoutExpiry); +@@ -419,7 +420,7 @@ + } + if (eomBufferWritten < EOM_BUFFER.length) { + // EOM has just been completed +- compressedPayload.limit(compressedPayload.limit() - EOM_BYTES.length + eomBufferWritten); ++ ((Buffer)compressedPayload).limit(compressedPayload.limit() - EOM_BYTES.length + eomBufferWritten); + compressedPart = new MessagePart(true, + getRsv(uncompressedPart), opCode, compressedPayload, + uncompressedIntermediateHandler, uncompressedIntermediateHandler, +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/WsFrameBase.java 2019-12-07 17:53:05.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/WsFrameBase.java 2020-01-20 10:42:16.535843952 +0100 +@@ -17,6 +17,7 @@ + package org.apache.tomcat.websocket; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.CharBuffer; + import java.nio.charset.CharsetDecoder; +@@ -91,7 +92,7 @@ + + public WsFrameBase(WsSession wsSession, Transformation transformation) { + inputBuffer = ByteBuffer.allocate(Constants.DEFAULT_BUFFER_SIZE); +- inputBuffer.position(0).limit(0); ++ ((Buffer)inputBuffer).position(0).limit(0); + messageBufferBinary = ByteBuffer.allocate(wsSession.getMaxBinaryMessageBufferSize()); + messageBufferText = CharBuffer.allocate(wsSession.getMaxTextMessageBufferSize()); + wsSession.setWsFrame(this); +@@ -257,11 +258,11 @@ + if (payloadLength == 126) { + payloadLength = byteArrayToLong(inputBuffer.array(), + inputBuffer.arrayOffset() + inputBuffer.position(), 2); +- inputBuffer.position(inputBuffer.position() + 2); ++ ((Buffer)inputBuffer).position(inputBuffer.position() + 2); + } else if (payloadLength == 127) { + payloadLength = byteArrayToLong(inputBuffer.array(), + inputBuffer.arrayOffset() + inputBuffer.position(), 8); +- inputBuffer.position(inputBuffer.position() + 8); ++ ((Buffer)inputBuffer).position(inputBuffer.position() + 8); + } + if (Util.isControl(opCode)) { + if (payloadLength > 125) { +@@ -313,13 +314,13 @@ + // Control messages have fixed message size so + // TransformationResult.OVERFLOW is not possible here + +- controlBufferBinary.flip(); ++ ((Buffer)controlBufferBinary).flip(); + if (opCode == Constants.OPCODE_CLOSE) { + open = false; + String reason = null; + int code = CloseCodes.NORMAL_CLOSURE.getCode(); + if (controlBufferBinary.remaining() == 1) { +- controlBufferBinary.clear(); ++ ((Buffer)controlBufferBinary).clear(); + // Payload must be zero or 2+ bytes long + throw new WsIOException(new CloseReason( + CloseCodes.PROTOCOL_ERROR, +@@ -331,8 +332,8 @@ + CoderResult cr = utf8DecoderControl.decode(controlBufferBinary, + controlBufferText, true); + if (cr.isError()) { +- controlBufferBinary.clear(); +- controlBufferText.clear(); ++ ((Buffer)controlBufferBinary).clear(); ++ ((Buffer)controlBufferText).clear(); + throw new WsIOException(new CloseReason( + CloseCodes.PROTOCOL_ERROR, + sm.getString("wsFrame.invalidUtf8Close"))); +@@ -340,7 +341,7 @@ + // There will be no overflow as the output buffer is big + // enough. There will be no underflow as all the data is + // passed to the decoder in a single call. +- controlBufferText.flip(); ++ ((Buffer)controlBufferText).flip(); + reason = controlBufferText.toString(); + } + } +@@ -357,17 +358,17 @@ + } catch (Throwable t) { + handleThrowableOnSend(t); + } finally { +- controlBufferBinary.clear(); ++ ((Buffer)controlBufferBinary).clear(); + } + } + } else { + // Should have caught this earlier but just in case... +- controlBufferBinary.clear(); ++ ((Buffer)controlBufferBinary).clear(); + throw new WsIOException(new CloseReason( + CloseCodes.PROTOCOL_ERROR, + sm.getString("wsFrame.invalidOpCode", Integer.valueOf(opCode)))); + } +- controlBufferBinary.clear(); ++ ((Buffer)controlBufferBinary).clear(); + newFrame(); + return true; + } +@@ -397,7 +398,7 @@ + } catch (Throwable t) { + handleThrowableOnSend(t); + } finally { +- messageBufferText.clear(); ++ ((Buffer)messageBufferText).clear(); + } + } + +@@ -408,7 +409,7 @@ + while (!TransformationResult.END_OF_FRAME.equals(tr)) { + // Frame not complete - we ran out of something + // Convert bytes to UTF-8 +- messageBufferBinary.flip(); ++ ((Buffer)messageBufferBinary).flip(); + while (true) { + CoderResult cr = utf8DecoderMessage.decode(messageBufferBinary, messageBufferText, + false); +@@ -419,9 +420,9 @@ + } else if (cr.isOverflow()) { + // Ran out of space in text buffer - flush it + if (usePartial()) { +- messageBufferText.flip(); ++ ((Buffer)messageBufferText).flip(); + sendMessageText(false); +- messageBufferText.clear(); ++ ((Buffer)messageBufferText).clear(); + } else { + throw new WsIOException(new CloseReason( + CloseCodes.TOO_BIG, +@@ -448,7 +449,7 @@ + tr = transformation.getMoreData(opCode, fin, rsv, messageBufferBinary); + } + +- messageBufferBinary.flip(); ++ ((Buffer)messageBufferBinary).flip(); + boolean last = false; + // Frame is fully received + // Convert bytes to UTF-8 +@@ -462,9 +463,9 @@ + } else if (cr.isOverflow()) { + // Ran out of space in text buffer - flush it + if (usePartial()) { +- messageBufferText.flip(); ++ ((Buffer)messageBufferText).flip(); + sendMessageText(false); +- messageBufferText.clear(); ++ ((Buffer)messageBufferText).clear(); + } else { + throw new WsIOException(new CloseReason( + CloseCodes.TOO_BIG, +@@ -477,9 +478,9 @@ + // If partial messages are supported, send what we have + // managed to decode + if (usePartial()) { +- messageBufferText.flip(); ++ ((Buffer)messageBufferText).flip(); + sendMessageText(false); +- messageBufferText.clear(); ++ ((Buffer)messageBufferText).clear(); + } + messageBufferBinary.compact(); + newFrame(); +@@ -491,7 +492,7 @@ + } + } else { + // End of message +- messageBufferText.flip(); ++ ((Buffer)messageBufferText).flip(); + sendMessageText(true); + + newMessage(); +@@ -519,12 +520,12 @@ + Long.valueOf(payloadLength))); + throw new WsIOException(cr); + } +- messageBufferBinary.flip(); ++ ((Buffer)messageBufferBinary).flip(); + ByteBuffer copy = ByteBuffer.allocate(messageBufferBinary.limit()); + copy.put(messageBufferBinary); +- copy.flip(); ++ ((Buffer)copy).flip(); + sendMessageBinary(copy, false); +- messageBufferBinary.clear(); ++ ((Buffer)messageBufferBinary).clear(); + // Read more data + tr = transformation.getMoreData(opCode, fin, rsv, messageBufferBinary); + } +@@ -534,12 +535,12 @@ + // - partial messages are supported + // - the message is complete + if (usePartial() || !continuationExpected) { +- messageBufferBinary.flip(); ++ ((Buffer)messageBufferBinary).flip(); + ByteBuffer copy = ByteBuffer.allocate(messageBufferBinary.limit()); + copy.put(messageBufferBinary); +- copy.flip(); ++ ((Buffer)copy).flip(); + sendMessageBinary(copy, !continuationExpected); +- messageBufferBinary.clear(); ++ ((Buffer)messageBufferBinary).clear(); + } + + if (continuationExpected) { +@@ -588,8 +589,8 @@ + + + private void newMessage() { +- messageBufferBinary.clear(); +- messageBufferText.clear(); ++ ((Buffer)messageBufferBinary).clear(); ++ ((Buffer)messageBufferText).clear(); + utf8DecoderMessage.reset(); + continuationExpected = false; + newFrame(); +@@ -598,7 +599,7 @@ + + private void newFrame() { + if (inputBuffer.remaining() == 0) { +- inputBuffer.position(0).limit(0); ++ ((Buffer)inputBuffer).position(0).limit(0); + } + + maskIndex = 0; +@@ -631,7 +632,7 @@ + + private void makeRoom() { + inputBuffer.compact(); +- inputBuffer.flip(); ++ ((Buffer)inputBuffer).flip(); + } + + +@@ -649,7 +650,7 @@ + + private boolean swallowInput() { + long toSkip = Math.min(payloadLength - payloadWritten, inputBuffer.remaining()); +- inputBuffer.position(inputBuffer.position() + (int) toSkip); ++ ((Buffer)inputBuffer).position(inputBuffer.position() + (int) toSkip); + payloadWritten += toSkip; + if (payloadWritten == payloadLength) { + if (continuationExpected) { +@@ -945,9 +946,9 @@ + toWrite = Math.min(toWrite, dest.remaining()); + + int orgLimit = inputBuffer.limit(); +- inputBuffer.limit(inputBuffer.position() + (int) toWrite); ++ ((Buffer)inputBuffer).limit(inputBuffer.position() + (int) toWrite); + dest.put(inputBuffer); +- inputBuffer.limit(orgLimit); ++ ((Buffer)inputBuffer).limit(orgLimit); + payloadWritten += toWrite; + + if (payloadWritten == payloadLength) { +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/WsFrameClient.java 2019-12-07 17:53:05.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/WsFrameClient.java 2020-01-20 10:47:43.889650987 +0100 +@@ -18,6 +18,7 @@ + + import java.io.EOFException; + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.CompletionHandler; + +@@ -76,8 +77,8 @@ + // and then a new socket read will be performed + return; + } +- inputBuffer.mark(); +- inputBuffer.position(inputBuffer.limit()).limit(inputBuffer.capacity()); ++ ((Buffer)inputBuffer).mark(); ++ ((Buffer)inputBuffer).position(inputBuffer.limit()).limit(inputBuffer.capacity()); + + int toCopy = Math.min(response.remaining(), inputBuffer.remaining()); + +@@ -85,16 +86,16 @@ + // frame processing + + int orgLimit = response.limit(); +- response.limit(response.position() + toCopy); ++ ((Buffer)response).limit(response.position() + toCopy); + inputBuffer.put(response); +- response.limit(orgLimit); ++ ((Buffer)response).limit(orgLimit); + +- inputBuffer.limit(inputBuffer.position()).reset(); ++ ((Buffer)inputBuffer).limit(inputBuffer.position()).reset(); + + // Process the data we have + processInputBuffer(); + } +- response.clear(); ++ ((Buffer)response).clear(); + + // Get some more data + if (isOpen()) { +@@ -159,7 +160,7 @@ + // No data to process + return; + } +- response.flip(); ++ ((Buffer)response).flip(); + doResumeProcessing(true); + } + +@@ -169,7 +170,7 @@ + // response will be empty if this exception is thrown + response = ByteBuffer + .allocate(((ReadBufferOverflowException) exc).getMinBufferSize()); +- response.flip(); ++ ((Buffer)response).flip(); + doResumeProcessing(false); + } else { + close(exc); +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 2019-12-07 17:53:05.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 2020-01-20 10:28:26.059200755 +0100 +@@ -20,6 +20,7 @@ + import java.io.OutputStream; + import java.io.Writer; + import java.net.SocketTimeoutException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.CharBuffer; + import java.nio.charset.CharsetEncoder; +@@ -240,13 +241,13 @@ + long timeoutExpiry = getTimeoutExpiry(); + boolean isDone = false; + while (!isDone) { +- encoderBuffer.clear(); ++ ((Buffer)encoderBuffer).clear(); + CoderResult cr = encoder.encode(part, encoderBuffer, true); + if (cr.isError()) { + throw new IllegalArgumentException(cr.toString()); + } + isDone = !cr.isOverflow(); +- encoderBuffer.flip(); ++ ((Buffer)encoderBuffer).flip(); + sendMessageBlock(Constants.OPCODE_TEXT, encoderBuffer, last && isDone, timeoutExpiry); + } + stateMachine.complete(last); +@@ -321,7 +322,7 @@ + } + + if (payload != null) { +- payload.clear(); ++ ((Buffer)payload).clear(); + } + + endMessage(null, null); +@@ -433,7 +434,7 @@ + if (Constants.INTERNAL_OPCODE_FLUSH == mp.getOpCode()) { + nextFragmented = fragmented; + nextText = text; +- outputBuffer.flip(); ++ ((Buffer)outputBuffer).flip(); + SendHandler flushHandler = new OutputBufferFlushSendHandler( + outputBuffer, mp.getEndHandler()); + doWrite(flushHandler, mp.getBlockingWriteTimeoutExpiry(), outputBuffer); +@@ -482,10 +483,10 @@ + mask = null; + } + +- headerBuffer.clear(); ++ ((Buffer)headerBuffer).clear(); + writeHeader(headerBuffer, mp.isFin(), mp.getRsv(), mp.getOpCode(), + isMasked(), mp.getPayload(), mask, first); +- headerBuffer.flip(); ++ ((Buffer)headerBuffer).flip(); + + if (getBatchingAllowed() || isMasked()) { + // Need to write via output buffer +@@ -798,13 +799,13 @@ + } + + public void write() { +- buffer.clear(); ++ ((Buffer)buffer).clear(); + CoderResult cr = encoder.encode(message, buffer, true); + if (cr.isError()) { + throw new IllegalArgumentException(cr.toString()); + } + isDone = !cr.isOverflow(); +- buffer.flip(); ++ ((Buffer)buffer).flip(); + endpoint.startMessage(Constants.OPCODE_TEXT, buffer, + isDone && isLast, this); + } +@@ -865,7 +866,7 @@ + } + if (headerBuffer.hasRemaining()) { + // Still more headers to write, need to flush +- outputBuffer.flip(); ++ ((Buffer)outputBuffer).flip(); + endpoint.doWrite(this, blockingWriteTimeoutExpiry, outputBuffer); + return; + } +@@ -879,7 +880,7 @@ + if (payloadLeft > outputSpace) { + toWrite = outputSpace; + // Temporarily reduce the limit +- payload.limit(payload.position() + toWrite); ++ ((Buffer)payload).limit(payload.position() + toWrite); + } + + if (mask == null) { +@@ -897,15 +898,15 @@ + + if (payloadLeft > outputSpace) { + // Restore the original limit +- payload.limit(payloadLimit); ++ ((Buffer)payload).limit(payloadLimit); + // Still more data to write, need to flush +- outputBuffer.flip(); ++ ((Buffer)outputBuffer).flip(); + endpoint.doWrite(this, blockingWriteTimeoutExpiry, outputBuffer); + return; + } + + if (flushRequired) { +- outputBuffer.flip(); ++ ((Buffer)outputBuffer).flip(); + if (outputBuffer.remaining() == 0) { + handler.onResult(SENDRESULT_OK); + } else { +@@ -923,7 +924,7 @@ + if (outputBuffer.hasRemaining()) { + endpoint.doWrite(this, blockingWriteTimeoutExpiry, outputBuffer); + } else { +- outputBuffer.clear(); ++ ((Buffer)outputBuffer).clear(); + write(); + } + } else { +@@ -949,7 +950,7 @@ + @Override + public void onResult(SendResult result) { + if (result.isOK()) { +- outputBuffer.clear(); ++ ((Buffer)outputBuffer).clear(); + } + handler.onResult(result); + } +@@ -1042,11 +1043,11 @@ + + private void doWrite(boolean last) throws IOException { + if (used) { +- buffer.flip(); ++ ((Buffer)buffer).flip(); + endpoint.sendMessageBlock(Constants.OPCODE_BINARY, buffer, last); + } + endpoint.stateMachine.complete(last); +- buffer.clear(); ++ ((Buffer)buffer).clear(); + } + } + +@@ -1121,9 +1122,9 @@ + + private void doWrite(boolean last) throws IOException { + if (used) { +- buffer.flip(); ++ ((Buffer)buffer).flip(); + endpoint.sendMessageBlock(buffer, last); +- buffer.clear(); ++ ((Buffer)buffer).clear(); + } else { + endpoint.stateMachine.complete(last); + } +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/WsSession.java 2019-12-07 17:53:05.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/WsSession.java 2020-01-20 10:13:22.326124937 +0100 +@@ -18,6 +18,7 @@ + + import java.io.IOException; + import java.net.URI; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.WritePendingException; + import java.nio.charset.StandardCharsets; +@@ -607,7 +608,7 @@ + if (reason != null && reason.length() > 0) { + appendCloseReasonWithTruncation(msg, reason); + } +- msg.flip(); ++ ((Buffer)msg).flip(); + try { + wsRemoteEndpoint.sendMessageBlock(Constants.OPCODE_CLOSE, msg, true); + } catch (IOException | WritePendingException e) { +--- apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/WsWebSocketContainer.java 2019-12-07 17:53:05.000000000 +0100 ++++ apache-tomcat-9.0.30-src/java/org/apache/tomcat/websocket/WsWebSocketContainer.java 2020-01-20 10:52:23.723195710 +0100 +@@ -27,6 +27,7 @@ + import java.net.SocketAddress; + import java.net.URI; + import java.net.URISyntaxException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.AsynchronousChannelGroup; + import java.nio.channels.AsynchronousSocketChannel; +@@ -742,7 +743,7 @@ + // Terminating CRLF + result.put(CRLF); + +- result.flip(); ++ ((Buffer)result).flip(); + + return result; + } +@@ -771,7 +772,7 @@ + newSize = input.capacity() * 2; + } + ByteBuffer expanded = ByteBuffer.allocate(newSize); +- input.flip(); ++ ((Buffer)input).flip(); + expanded.put(input); + input = expanded; + } +@@ -800,14 +801,14 @@ + while (!readHeaders) { + // On entering loop buffer will be empty and at the start of a new + // loop the buffer will have been fully read. +- response.clear(); ++ ((Buffer)response).clear(); + // Blocking read + Future read = channel.read(response); + Integer bytesRead = read.get(timeout, TimeUnit.MILLISECONDS); + if (bytesRead.intValue() == -1) { + throw new EOFException(); + } +- response.flip(); ++ ((Buffer)response).flip(); + while (response.hasRemaining() && !readHeaders) { + if (line == null) { + line = readLine(response); +--- apache-tomcat-9.0.30-src/test/org/apache/coyote/http11/upgrade/TestUpgradeInternalHandler.java 2019-12-07 17:53:15.000000000 +0100 ++++ apache-tomcat-9.0.30-src/test/org/apache/coyote/http11/upgrade/TestUpgradeInternalHandler.java 2020-01-20 08:48:46.225260991 +0100 +@@ -25,6 +25,7 @@ + import java.io.PrintWriter; + import java.io.Writer; + import java.net.Socket; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.CompletionHandler; + import java.nio.charset.StandardCharsets; +@@ -215,7 +216,7 @@ + } + + private void write(ByteBuffer buffer) { +- buffer.flip(); ++ ((Buffer)buffer).flip(); + CompletionState state = wrapper.write(BlockingMode.BLOCK, 10, TimeUnit.SECONDS, null, SocketWrapperBase.COMPLETE_WRITE, new CompletionHandler() { + @Override + public void completed(Long result, Void attachment) { +--- apache-tomcat-9.0.30-src/test/org/apache/coyote/http2/Http2TestBase.java 2019-12-07 17:53:15.000000000 +0100 ++++ apache-tomcat-9.0.30-src/test/org/apache/coyote/http2/Http2TestBase.java 2020-01-20 08:30:19.803288844 +0100 +@@ -23,6 +23,7 @@ + import java.io.OutputStream; + import java.net.Socket; + import java.net.SocketException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.charset.StandardCharsets; + import java.util.ArrayList; +@@ -217,7 +218,7 @@ + if (padding != null) { + headersPayload.put(padding); + } +- headersPayload.flip(); ++ ((Buffer)headersPayload).flip(); + + ByteUtil.setThreeBytes(frameHeader, 0, headersPayload.limit()); + frameHeader[3] = FrameType.HEADERS.getIdByte(); +@@ -250,7 +251,7 @@ + } + hpackEncoder.encode(mimeHeaders, headersPayload); + +- headersPayload.flip(); ++ ((Buffer)headersPayload).flip(); + + ByteUtil.setThreeBytes(frameHeader, 0, headersPayload.limit()); + frameHeader[3] = FrameType.HEADERS.getIdByte(); +@@ -278,7 +279,7 @@ + } + hpackEncoder.encode(mimeHeaders, headersPayload); + +- headersPayload.flip(); ++ ((Buffer)headersPayload).flip(); + + ByteUtil.setThreeBytes(frameHeader, 0, headersPayload.limit()); + frameHeader[3] = FrameType.CONTINUATION.getIdByte(); +@@ -368,7 +369,7 @@ + } + hpackEncoder.encode(headers, headersPayload); + +- headersPayload.flip(); ++ ((Buffer)headersPayload).flip(); + + ByteUtil.setThreeBytes(headersFrameHeader, 0, headersPayload.limit()); + headersFrameHeader[3] = FrameType.HEADERS.getIdByte(); +@@ -380,18 +381,18 @@ + // Data + if (padding != null) { + dataPayload.put((byte) (padding.length & 0xFF)); +- dataPayload.limit(dataPayload.capacity() - padding.length); ++ ((Buffer)dataPayload).limit(dataPayload.capacity() - padding.length); + } + + while (dataPayload.hasRemaining()) { + dataPayload.put((byte) 'x'); + } + if (padding != null && padding.length > 0) { +- dataPayload.limit(dataPayload.capacity()); ++ ((Buffer)dataPayload).limit(dataPayload.capacity()); + dataPayload.put(padding); + } + +- dataPayload.flip(); ++ ((Buffer)dataPayload).flip(); + + // Size + ByteUtil.setThreeBytes(dataFrameHeader, 0, dataPayload.limit()); +@@ -413,7 +414,7 @@ + trailerHeaders.addValue(TRAILER_HEADER_NAME).setString(TRAILER_HEADER_VALUE); + hpackEncoder.encode(trailerHeaders, trailersPayload); + +- trailersPayload.flip(); ++ ((Buffer)trailersPayload).flip(); + + ByteUtil.setThreeBytes(trailersFrameHeader, 0, trailersPayload.limit()); + trailersFrameHeader[3] = FrameType.HEADERS.getIdByte(); +@@ -989,7 +990,7 @@ + if (bodyBuffer != null) { + if (bodyBuffer.limit() > 0) { + trace.append(lastStreamId + "-Body-"); +- bodyBuffer.flip(); ++ ((Buffer)bodyBuffer).flip(); + while (bodyBuffer.hasRemaining()) { + trace.append((char) bodyBuffer.get()); + } +--- apache-tomcat-9.0.30-src/test/org/apache/coyote/http2/TestHpack.java 2019-12-07 17:53:15.000000000 +0100 ++++ apache-tomcat-9.0.30-src/test/org/apache/coyote/http2/TestHpack.java 2020-01-20 08:39:21.734214027 +0100 +@@ -16,6 +16,7 @@ + */ + package org.apache.coyote.http2; + ++import java.nio.Buffer; + import java.nio.ByteBuffer; + + import org.junit.Assert; +@@ -34,13 +35,13 @@ + ByteBuffer output = ByteBuffer.allocate(512); + HpackEncoder encoder = new HpackEncoder(); + encoder.encode(headers, output); +- output.flip(); ++ ((Buffer)output).flip(); + // Size is supposed to be 33 without huffman, or 27 with it + // TODO: use the HpackHeaderFunction to enable huffman predictably + Assert.assertEquals(27, output.remaining()); +- output.clear(); ++ ((Buffer)output).clear(); + encoder.encode(headers, output); +- output.flip(); ++ ((Buffer)output).flip(); + // Size is now 3 after using the table + Assert.assertEquals(3, output.remaining()); + } +@@ -54,15 +55,15 @@ + ByteBuffer output = ByteBuffer.allocate(512); + HpackEncoder encoder = new HpackEncoder(); + encoder.encode(headers, output); +- output.flip(); ++ ((Buffer)output).flip(); + MimeHeaders headers2 = new MimeHeaders(); + HpackDecoder decoder = new HpackDecoder(); + decoder.setHeaderEmitter(new HeadersListener(headers2)); + decoder.decode(output); + // Redo (table is supposed to be updated) +- output.clear(); ++ ((Buffer)output).clear(); + encoder.encode(headers, output); +- output.flip(); ++ ((Buffer)output).flip(); + headers2.recycle(); + Assert.assertEquals(3, output.remaining()); + // Check that the decoder is using the table right +@@ -120,7 +121,7 @@ + // by another byte + output.array()[7] = (byte) -122; + output.put((byte) -1); +- output.flip(); ++ ((Buffer)output).flip(); + MimeHeaders headers2 = new MimeHeaders(); + HpackDecoder decoder = new HpackDecoder(); + decoder.setHeaderEmitter(new HeadersListener(headers2)); +@@ -136,7 +137,7 @@ + ByteBuffer output = ByteBuffer.allocate(512); + HpackEncoder encoder = new HpackEncoder(); + encoder.encode(headers, output); +- output.flip(); ++ ((Buffer)output).flip(); + MimeHeaders headers2 = new MimeHeaders(); + HpackDecoder decoder = new HpackDecoder(); + decoder.setHeaderEmitter(new HeadersListener(headers2)); +--- apache-tomcat-9.0.30-src/test/org/apache/coyote/http2/TestHttp2Limits.java 2019-12-07 17:53:15.000000000 +0100 ++++ apache-tomcat-9.0.30-src/test/org/apache/coyote/http2/TestHttp2Limits.java 2020-01-20 08:35:41.669026197 +0100 +@@ -17,6 +17,7 @@ + package org.apache.coyote.http2; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.util.ArrayList; + import java.util.List; +@@ -290,7 +291,7 @@ + if (state != State.COMPLETE) { + throw new Exception("Unable to build headers"); + } +- headersPayload.flip(); ++ ((Buffer)headersPayload).flip(); + + log.debug("Headers payload generated of size [" + headersPayload.limit() + "]"); + } +--- apache-tomcat-9.0.30-src/test/org/apache/coyote/http2/TestHttp2Section_8_1.java 2019-12-07 17:53:16.000000000 +0100 ++++ apache-tomcat-9.0.30-src/test/org/apache/coyote/http2/TestHttp2Section_8_1.java 2020-01-20 08:45:36.024234324 +0100 +@@ -16,6 +16,7 @@ + */ + package org.apache.coyote.http2; + ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.util.ArrayList; + import java.util.List; +@@ -186,7 +187,7 @@ + + headers.clear(); + headers.add(new Header(":authority", "localhost:" + getPort())); +- headersPayload.clear(); ++ ((Buffer)headersPayload).clear(); + + buildSimpleGetRequestPart2(headersFrameHeader, headersPayload, headers , 3); + +--- apache-tomcat-9.0.30-src/test/org/apache/tomcat/util/buf/TestUtf8.java 2019-12-07 17:53:18.000000000 +0100 ++++ apache-tomcat-9.0.30-src/test/org/apache/tomcat/util/buf/TestUtf8.java 2020-01-20 09:00:05.388933377 +0100 +@@ -16,6 +16,7 @@ + */ + package org.apache.tomcat.util.buf; + ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.CharBuffer; + import java.nio.charset.CharsetDecoder; +@@ -579,7 +580,7 @@ + // an invalid sequence has been provided + for (int i = 0; i < len; i++) { + bb.put((byte) testCase.input[i]); +- bb.flip(); ++ ((Buffer)bb).flip(); + CoderResult cr = decoder.decode(bb, cb, false); + if (cr.isError()) { + int expected = testCase.invalidIndex; +@@ -604,11 +605,11 @@ + decoder.onUnmappableCharacter(CodingErrorAction.REPLACE); + + // Add each byte one at a time. +- bb.clear(); +- cb.clear(); ++ ((Buffer)bb).clear(); ++ ((Buffer)cb).clear(); + for (int i = 0; i < len; i++) { + bb.put((byte) testCase.input[i]); +- bb.flip(); ++ ((Buffer)bb).flip(); + CoderResult cr = decoder.decode(bb, cb, false); + if (cr.isError()) { + Assert.fail(testCase.description); +@@ -617,12 +618,12 @@ + } + // For incomplete sequences at the end of the input need to tell + // the decoder the input has ended +- bb.flip(); ++ ((Buffer)bb).flip(); + CoderResult cr = decoder.decode(bb, cb, true); + if (cr.isError()) { + Assert.fail(testCase.description); + } +- cb.flip(); ++ ((Buffer)cb).flip(); + + String expected = testCase.outputReplaced; + if ((flags & REPLACE_SWALLOWS_TRAILER) != 0) { +--- apache-tomcat-9.0.30-src/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java 2019-12-07 17:53:20.000000000 +0100 ++++ apache-tomcat-9.0.30-src/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java 2020-01-20 08:51:01.857993078 +0100 +@@ -18,6 +18,7 @@ + + import java.io.IOException; + import java.net.URI; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.util.ArrayList; + import java.util.Collections; +@@ -604,7 +605,7 @@ + reply.put((byte) 0x12); + reply.put((byte) 0x34); + reply.put(data); +- reply.flip(); ++ ((Buffer)reply).flip(); + return reply; + } + } diff --git a/tomcat.changes b/tomcat.changes index b4ad160..cc0f352 100644 --- a/tomcat.changes +++ b/tomcat.changes @@ -1,3 +1,18 @@ +------------------------------------------------------------------- +Mon Jan 20 13:36:39 UTC 2020 - Fridrich Strba + +- Change back the build to build with any Java >= 1.8 +- Added patch: + * tomcat-9.0.30-java8compat.patch + + Cast java.nio.ByteBuffer and java.nio.CharBuffer to + java.nio.Buffer in order to avoid calling Java 9+ APIs + (functions with co-variant return types) +- Renamed patch: + * tomcat-9.0-disable-osgi-build.patch + -> tomcat-9.0-osgi-build.patch + + Do not disable, but fix OSGi build since we have now + aqute-bnd + ------------------------------------------------------------------- Fri Jan 17 14:26:15 UTC 2020 - Matei Albu diff --git a/tomcat.spec b/tomcat.spec index ed32ee3..d8a8e5c 100644 --- a/tomcat.spec +++ b/tomcat.spec @@ -1,7 +1,7 @@ # # spec file for package tomcat # -# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # Copyright (c) 2000-2009, JPackage Project # # All modifications and additions to the file contributed by third parties @@ -77,8 +77,10 @@ Patch1: %{name}-%{major_version}.%{minor_version}-tomcat-users-webapp.pa Patch2: %{name}-%{major_version}.%{minor_version}-sle.catalina.policy.patch # PATCH-FIX-OPENSUSE: build javadoc with the same java source level as the class files Patch3: %{name}-%{major_version}.%{minor_version}-javadoc.patch -# PATCH-FIX-OPENSUSE: disable adding OSGi metadata to JAR files because bndtools is not avalable in SLES/OpenSUSE -Patch4: tomcat-9.0-disable-osgi-build.patch +# PATCH-FIX-OPENSUSE: include all necessary aqute-bnd jars +Patch4: tomcat-9.0-osgi-build.patch +# PATCH-FIX-OPENSUSE: cast ByteBuffer to Buffer in cases where there is a risk of using Java 9+ apis +Patch5: tomcat-9.0.30-java8compat.patch BuildRequires: ant >= 1.8.1 BuildRequires: ant-antlr @@ -96,9 +98,8 @@ BuildRequires: geronimo-jaxrpc-1_1-api BuildRequires: geronimo-qname-1_1-api BuildRequires: geronimo-saaj-1_1-api BuildRequires: jakarta-taglibs-standard >= 1.1 -BuildRequires: java-devel = 1.8.0 +BuildRequires: java-devel >= 1.8 BuildRequires: javapackages-local -BuildRequires: javapackages-tools BuildRequires: junit BuildRequires: log4j12 BuildRequires: sed @@ -256,6 +257,7 @@ find . -type f \( -name "*.bat" -o -name "*.class" -o -name Thumbs.db -o -name " %patch2 %patch3 -p1 %patch4 -p1 +%patch5 -p1 # remove date from docs sed -i -e '/build-date/ d' webapps/docs/tomcat-docs.xsl