From 406a4eafa25ccd8f456622be19e2ce1e624bc227 Mon Sep 17 00:00:00 2001 From: cpovirk Date: Thu, 20 Aug 2020 10:39:53 -0700 Subject: [PATCH] Don't directly call ByteBuffer, etc. methods that have covariant returns in Java 9+. Doing so produces a jar that doesn't work under Java 8. This CL addresses the currently existing problematic calls (by calling the methods on the supertype Buffer instead), but we should also add safeguards. The normal solution to this general problem is to use --release, but doing so here is complicated. For more information, see https://github.com/google/guava/issues/3990 RELNOTES=n/a ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=327654073 --- .../common/hash/AbstractByteHasher.java | 4 +- .../hash/AbstractCompositeHashFunction.java | 2 +- .../google/common/hash/AbstractHasher.java | 2 +- .../common/hash/AbstractStreamingHasher.java | 14 +++--- .../common/hash/Java8Compatibility.java | 43 +++++++++++++++++++ .../src/com/google/common/io/ByteStreams.java | 4 +- .../src/com/google/common/io/CharStreams.java | 6 +-- .../google/common/io/Java8Compatibility.java | 43 +++++++++++++++++++ .../src/com/google/common/io/LineReader.java | 2 +- .../google/common/io/ReaderInputStream.java | 14 +++--- .../common/hash/AbstractByteHasher.java | 4 +- .../hash/AbstractCompositeHashFunction.java | 2 +- .../google/common/hash/AbstractHasher.java | 2 +- .../common/hash/AbstractStreamingHasher.java | 14 +++--- .../common/hash/Java8Compatibility.java | 43 +++++++++++++++++++ .../src/com/google/common/io/ByteStreams.java | 4 +- .../src/com/google/common/io/CharStreams.java | 6 +-- .../google/common/io/Java8Compatibility.java | 43 +++++++++++++++++++ .../src/com/google/common/io/LineReader.java | 2 +- .../google/common/io/ReaderInputStream.java | 14 +++--- 20 files changed, 220 insertions(+), 48 deletions(-) create mode 100644 android/guava/src/com/google/common/hash/Java8Compatibility.java create mode 100644 android/guava/src/com/google/common/io/Java8Compatibility.java create mode 100644 guava/src/com/google/common/hash/Java8Compatibility.java create mode 100644 guava/src/com/google/common/io/Java8Compatibility.java diff --git a/android/guava/src/com/google/common/hash/AbstractByteHasher.java b/android/guava/src/com/google/common/hash/AbstractByteHasher.java index 668320e3e681..48d48c489bf8 100644 --- a/android/guava/src/com/google/common/hash/AbstractByteHasher.java +++ b/android/guava/src/com/google/common/hash/AbstractByteHasher.java @@ -54,7 +54,7 @@ protected void update(byte[] b, int off, int len) { protected void update(ByteBuffer b) { if (b.hasArray()) { update(b.array(), b.arrayOffset() + b.position(), b.remaining()); - b.position(b.limit()); + Java8Compatibility.position(b, b.limit()); } else { for (int remaining = b.remaining(); remaining > 0; remaining--) { update(b.get()); @@ -67,7 +67,7 @@ private Hasher update(int bytes) { try { update(scratch.array(), 0, bytes); } finally { - scratch.clear(); + Java8Compatibility.clear(scratch); } return this; } diff --git a/android/guava/src/com/google/common/hash/AbstractCompositeHashFunction.java b/android/guava/src/com/google/common/hash/AbstractCompositeHashFunction.java index 525ead84c1d0..048e6c23587a 100644 --- a/android/guava/src/com/google/common/hash/AbstractCompositeHashFunction.java +++ b/android/guava/src/com/google/common/hash/AbstractCompositeHashFunction.java @@ -98,7 +98,7 @@ public Hasher putBytes(byte[] bytes, int off, int len) { public Hasher putBytes(ByteBuffer bytes) { int pos = bytes.position(); for (Hasher hasher : hashers) { - bytes.position(pos); + Java8Compatibility.position(bytes, pos); hasher.putBytes(bytes); } return this; diff --git a/android/guava/src/com/google/common/hash/AbstractHasher.java b/android/guava/src/com/google/common/hash/AbstractHasher.java index 3452fb3c93df..326aa8df657f 100644 --- a/android/guava/src/com/google/common/hash/AbstractHasher.java +++ b/android/guava/src/com/google/common/hash/AbstractHasher.java @@ -73,7 +73,7 @@ public Hasher putBytes(byte[] bytes, int off, int len) { public Hasher putBytes(ByteBuffer b) { if (b.hasArray()) { putBytes(b.array(), b.arrayOffset() + b.position(), b.remaining()); - b.position(b.limit()); + Java8Compatibility.position(b, b.limit()); } else { for (int remaining = b.remaining(); remaining > 0; remaining--) { putByte(b.get()); diff --git a/android/guava/src/com/google/common/hash/AbstractStreamingHasher.java b/android/guava/src/com/google/common/hash/AbstractStreamingHasher.java index ae05d1cb23e1..67de74baf599 100644 --- a/android/guava/src/com/google/common/hash/AbstractStreamingHasher.java +++ b/android/guava/src/com/google/common/hash/AbstractStreamingHasher.java @@ -80,13 +80,13 @@ protected AbstractStreamingHasher(int chunkSize, int bufferSize) { *

This implementation simply pads with zeros and delegates to {@link #process(ByteBuffer)}. */ protected void processRemaining(ByteBuffer bb) { - bb.position(bb.limit()); // move at the end - bb.limit(chunkSize + 7); // get ready to pad with longs + Java8Compatibility.position(bb, bb.limit()); // move at the end + Java8Compatibility.limit(bb, chunkSize + 7); // get ready to pad with longs while (bb.position() < chunkSize) { bb.putLong(0); } - bb.limit(chunkSize); - bb.flip(); + Java8Compatibility.limit(bb, chunkSize); + Java8Compatibility.flip(bb); process(bb); } @@ -179,10 +179,10 @@ public final Hasher putLong(long l) { @Override public final HashCode hash() { munch(); - buffer.flip(); + Java8Compatibility.flip(buffer); if (buffer.remaining() > 0) { processRemaining(buffer); - buffer.position(buffer.limit()); + Java8Compatibility.position(buffer, buffer.limit()); } return makeHash(); } @@ -203,7 +203,7 @@ private void munchIfFull() { } private void munch() { - buffer.flip(); + Java8Compatibility.flip(buffer); while (buffer.remaining() >= chunkSize) { // we could limit the buffer to ensure process() does not read more than // chunkSize number of bytes, but we trust the implementations diff --git a/android/guava/src/com/google/common/hash/Java8Compatibility.java b/android/guava/src/com/google/common/hash/Java8Compatibility.java new file mode 100644 index 000000000000..52f71e788558 --- /dev/null +++ b/android/guava/src/com/google/common/hash/Java8Compatibility.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.hash; + +import com.google.common.annotations.GwtIncompatible; +import java.nio.Buffer; + +/** + * Wrappers around {@link Buffer} methods that are covariantly overridden in Java 9+. See + * https://github.com/google/guava/issues/3990 + */ +@GwtIncompatible +final class Java8Compatibility { + static void clear(Buffer b) { + b.clear(); + } + + static void flip(Buffer b) { + b.flip(); + } + + static void limit(Buffer b, int limit) { + b.limit(limit); + } + + static void position(Buffer b, int position) { + b.position(position); + } + + private Java8Compatibility() {} +} diff --git a/android/guava/src/com/google/common/io/ByteStreams.java b/android/guava/src/com/google/common/io/ByteStreams.java index 05d77cd9a68a..9becd4223eb9 100644 --- a/android/guava/src/com/google/common/io/ByteStreams.java +++ b/android/guava/src/com/google/common/io/ByteStreams.java @@ -145,11 +145,11 @@ public static long copy(ReadableByteChannel from, WritableByteChannel to) throws ByteBuffer buf = ByteBuffer.wrap(createBuffer()); long total = 0; while (from.read(buf) != -1) { - buf.flip(); + Java8Compatibility.flip(buf); while (buf.hasRemaining()) { total += to.write(buf); } - buf.clear(); + Java8Compatibility.clear(buf); } return total; } diff --git a/android/guava/src/com/google/common/io/CharStreams.java b/android/guava/src/com/google/common/io/CharStreams.java index 2e919dcfe3f9..e54284eaa7bb 100644 --- a/android/guava/src/com/google/common/io/CharStreams.java +++ b/android/guava/src/com/google/common/io/CharStreams.java @@ -83,10 +83,10 @@ public static long copy(Readable from, Appendable to) throws IOException { long total = 0; CharBuffer buf = createBuffer(); while (from.read(buf) != -1) { - buf.flip(); + Java8Compatibility.flip(buf); to.append(buf); total += buf.remaining(); - buf.clear(); + Java8Compatibility.clear(buf); } return total; } @@ -243,7 +243,7 @@ public static long exhaust(Readable readable) throws IOException { CharBuffer buf = createBuffer(); while ((read = readable.read(buf)) != -1) { total += read; - buf.clear(); + Java8Compatibility.clear(buf); } return total; } diff --git a/android/guava/src/com/google/common/io/Java8Compatibility.java b/android/guava/src/com/google/common/io/Java8Compatibility.java new file mode 100644 index 000000000000..62b5c2ea5b7f --- /dev/null +++ b/android/guava/src/com/google/common/io/Java8Compatibility.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.io; + +import com.google.common.annotations.GwtIncompatible; +import java.nio.Buffer; + +/** + * Wrappers around {@link Buffer} methods that are covariantly overridden in Java 9+. See + * https://github.com/google/guava/issues/3990 + */ +@GwtIncompatible +final class Java8Compatibility { + static void clear(Buffer b) { + b.clear(); + } + + static void flip(Buffer b) { + b.flip(); + } + + static void limit(Buffer b, int limit) { + b.limit(limit); + } + + static void position(Buffer b, int position) { + b.position(position); + } + + private Java8Compatibility() {} +} diff --git a/android/guava/src/com/google/common/io/LineReader.java b/android/guava/src/com/google/common/io/LineReader.java index 8514a2985727..1c8cef0b7162 100644 --- a/android/guava/src/com/google/common/io/LineReader.java +++ b/android/guava/src/com/google/common/io/LineReader.java @@ -70,7 +70,7 @@ public LineReader(Readable readable) { @CanIgnoreReturnValue // to skip a line public String readLine() throws IOException { while (lines.peek() == null) { - cbuf.clear(); + Java8Compatibility.clear(cbuf); // The default implementation of Reader#read(CharBuffer) allocates a // temporary char[], so we call Reader#read(char[], int, int) instead. int read = (reader != null) ? reader.read(buf, 0, buf.length) : readable.read(cbuf); diff --git a/android/guava/src/com/google/common/io/ReaderInputStream.java b/android/guava/src/com/google/common/io/ReaderInputStream.java index 9cbca93b8e93..eeb64e4e0d8c 100644 --- a/android/guava/src/com/google/common/io/ReaderInputStream.java +++ b/android/guava/src/com/google/common/io/ReaderInputStream.java @@ -104,7 +104,7 @@ final class ReaderInputStream extends InputStream { encoder.reset(); charBuffer = CharBuffer.allocate(bufferSize); - charBuffer.flip(); + Java8Compatibility.flip(charBuffer); byteBuffer = ByteBuffer.allocate(bufferSize); } @@ -143,7 +143,7 @@ public int read(byte[] b, int off, int len) throws IOException { return (totalBytesRead > 0) ? totalBytesRead : -1; } draining = false; - byteBuffer.clear(); + Java8Compatibility.clear(byteBuffer); } while (true) { @@ -189,8 +189,8 @@ public int read(byte[] b, int off, int len) throws IOException { private static CharBuffer grow(CharBuffer buf) { char[] copy = Arrays.copyOf(buf.array(), buf.capacity() * 2); CharBuffer bigger = CharBuffer.wrap(copy); - bigger.position(buf.position()); - bigger.limit(buf.limit()); + Java8Compatibility.position(bigger, buf.position()); + Java8Compatibility.limit(bigger, buf.limit()); return bigger; } @@ -207,7 +207,7 @@ private void readMoreChars() throws IOException { if (availableCapacity(charBuffer) == 0) { if (charBuffer.position() > 0) { // (2) There is room in the buffer. Move existing bytes to the beginning. - charBuffer.compact().flip(); + Java8Compatibility.flip(charBuffer.compact()); } else { // (3) Entire buffer is full, need bigger buffer. charBuffer = grow(charBuffer); @@ -220,7 +220,7 @@ private void readMoreChars() throws IOException { if (numChars == -1) { endOfInput = true; } else { - charBuffer.limit(limit + numChars); + Java8Compatibility.limit(charBuffer, limit + numChars); } } @@ -235,7 +235,7 @@ private static int availableCapacity(Buffer buffer) { * overflow must be due to a small output buffer. */ private void startDraining(boolean overflow) { - byteBuffer.flip(); + Java8Compatibility.flip(byteBuffer); if (overflow && byteBuffer.remaining() == 0) { byteBuffer = ByteBuffer.allocate(byteBuffer.capacity() * 2); } else { diff --git a/guava/src/com/google/common/hash/AbstractByteHasher.java b/guava/src/com/google/common/hash/AbstractByteHasher.java index 668320e3e681..48d48c489bf8 100644 --- a/guava/src/com/google/common/hash/AbstractByteHasher.java +++ b/guava/src/com/google/common/hash/AbstractByteHasher.java @@ -54,7 +54,7 @@ protected void update(byte[] b, int off, int len) { protected void update(ByteBuffer b) { if (b.hasArray()) { update(b.array(), b.arrayOffset() + b.position(), b.remaining()); - b.position(b.limit()); + Java8Compatibility.position(b, b.limit()); } else { for (int remaining = b.remaining(); remaining > 0; remaining--) { update(b.get()); @@ -67,7 +67,7 @@ private Hasher update(int bytes) { try { update(scratch.array(), 0, bytes); } finally { - scratch.clear(); + Java8Compatibility.clear(scratch); } return this; } diff --git a/guava/src/com/google/common/hash/AbstractCompositeHashFunction.java b/guava/src/com/google/common/hash/AbstractCompositeHashFunction.java index 525ead84c1d0..048e6c23587a 100644 --- a/guava/src/com/google/common/hash/AbstractCompositeHashFunction.java +++ b/guava/src/com/google/common/hash/AbstractCompositeHashFunction.java @@ -98,7 +98,7 @@ public Hasher putBytes(byte[] bytes, int off, int len) { public Hasher putBytes(ByteBuffer bytes) { int pos = bytes.position(); for (Hasher hasher : hashers) { - bytes.position(pos); + Java8Compatibility.position(bytes, pos); hasher.putBytes(bytes); } return this; diff --git a/guava/src/com/google/common/hash/AbstractHasher.java b/guava/src/com/google/common/hash/AbstractHasher.java index 3452fb3c93df..326aa8df657f 100644 --- a/guava/src/com/google/common/hash/AbstractHasher.java +++ b/guava/src/com/google/common/hash/AbstractHasher.java @@ -73,7 +73,7 @@ public Hasher putBytes(byte[] bytes, int off, int len) { public Hasher putBytes(ByteBuffer b) { if (b.hasArray()) { putBytes(b.array(), b.arrayOffset() + b.position(), b.remaining()); - b.position(b.limit()); + Java8Compatibility.position(b, b.limit()); } else { for (int remaining = b.remaining(); remaining > 0; remaining--) { putByte(b.get()); diff --git a/guava/src/com/google/common/hash/AbstractStreamingHasher.java b/guava/src/com/google/common/hash/AbstractStreamingHasher.java index ae05d1cb23e1..67de74baf599 100644 --- a/guava/src/com/google/common/hash/AbstractStreamingHasher.java +++ b/guava/src/com/google/common/hash/AbstractStreamingHasher.java @@ -80,13 +80,13 @@ protected AbstractStreamingHasher(int chunkSize, int bufferSize) { *

This implementation simply pads with zeros and delegates to {@link #process(ByteBuffer)}. */ protected void processRemaining(ByteBuffer bb) { - bb.position(bb.limit()); // move at the end - bb.limit(chunkSize + 7); // get ready to pad with longs + Java8Compatibility.position(bb, bb.limit()); // move at the end + Java8Compatibility.limit(bb, chunkSize + 7); // get ready to pad with longs while (bb.position() < chunkSize) { bb.putLong(0); } - bb.limit(chunkSize); - bb.flip(); + Java8Compatibility.limit(bb, chunkSize); + Java8Compatibility.flip(bb); process(bb); } @@ -179,10 +179,10 @@ public final Hasher putLong(long l) { @Override public final HashCode hash() { munch(); - buffer.flip(); + Java8Compatibility.flip(buffer); if (buffer.remaining() > 0) { processRemaining(buffer); - buffer.position(buffer.limit()); + Java8Compatibility.position(buffer, buffer.limit()); } return makeHash(); } @@ -203,7 +203,7 @@ private void munchIfFull() { } private void munch() { - buffer.flip(); + Java8Compatibility.flip(buffer); while (buffer.remaining() >= chunkSize) { // we could limit the buffer to ensure process() does not read more than // chunkSize number of bytes, but we trust the implementations diff --git a/guava/src/com/google/common/hash/Java8Compatibility.java b/guava/src/com/google/common/hash/Java8Compatibility.java new file mode 100644 index 000000000000..52f71e788558 --- /dev/null +++ b/guava/src/com/google/common/hash/Java8Compatibility.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.hash; + +import com.google.common.annotations.GwtIncompatible; +import java.nio.Buffer; + +/** + * Wrappers around {@link Buffer} methods that are covariantly overridden in Java 9+. See + * https://github.com/google/guava/issues/3990 + */ +@GwtIncompatible +final class Java8Compatibility { + static void clear(Buffer b) { + b.clear(); + } + + static void flip(Buffer b) { + b.flip(); + } + + static void limit(Buffer b, int limit) { + b.limit(limit); + } + + static void position(Buffer b, int position) { + b.position(position); + } + + private Java8Compatibility() {} +} diff --git a/guava/src/com/google/common/io/ByteStreams.java b/guava/src/com/google/common/io/ByteStreams.java index 05d77cd9a68a..9becd4223eb9 100644 --- a/guava/src/com/google/common/io/ByteStreams.java +++ b/guava/src/com/google/common/io/ByteStreams.java @@ -145,11 +145,11 @@ public static long copy(ReadableByteChannel from, WritableByteChannel to) throws ByteBuffer buf = ByteBuffer.wrap(createBuffer()); long total = 0; while (from.read(buf) != -1) { - buf.flip(); + Java8Compatibility.flip(buf); while (buf.hasRemaining()) { total += to.write(buf); } - buf.clear(); + Java8Compatibility.clear(buf); } return total; } diff --git a/guava/src/com/google/common/io/CharStreams.java b/guava/src/com/google/common/io/CharStreams.java index 458f40d525cb..dd54253928d5 100644 --- a/guava/src/com/google/common/io/CharStreams.java +++ b/guava/src/com/google/common/io/CharStreams.java @@ -83,10 +83,10 @@ public static long copy(Readable from, Appendable to) throws IOException { long total = 0; CharBuffer buf = createBuffer(); while (from.read(buf) != -1) { - buf.flip(); + Java8Compatibility.flip(buf); to.append(buf); total += buf.remaining(); - buf.clear(); + Java8Compatibility.clear(buf); } return total; } @@ -243,7 +243,7 @@ public static long exhaust(Readable readable) throws IOException { CharBuffer buf = createBuffer(); while ((read = readable.read(buf)) != -1) { total += read; - buf.clear(); + Java8Compatibility.clear(buf); } return total; } diff --git a/guava/src/com/google/common/io/Java8Compatibility.java b/guava/src/com/google/common/io/Java8Compatibility.java new file mode 100644 index 000000000000..62b5c2ea5b7f --- /dev/null +++ b/guava/src/com/google/common/io/Java8Compatibility.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.io; + +import com.google.common.annotations.GwtIncompatible; +import java.nio.Buffer; + +/** + * Wrappers around {@link Buffer} methods that are covariantly overridden in Java 9+. See + * https://github.com/google/guava/issues/3990 + */ +@GwtIncompatible +final class Java8Compatibility { + static void clear(Buffer b) { + b.clear(); + } + + static void flip(Buffer b) { + b.flip(); + } + + static void limit(Buffer b, int limit) { + b.limit(limit); + } + + static void position(Buffer b, int position) { + b.position(position); + } + + private Java8Compatibility() {} +} diff --git a/guava/src/com/google/common/io/LineReader.java b/guava/src/com/google/common/io/LineReader.java index 1ccb4d12b8b9..55b659f27128 100644 --- a/guava/src/com/google/common/io/LineReader.java +++ b/guava/src/com/google/common/io/LineReader.java @@ -70,7 +70,7 @@ public LineReader(Readable readable) { @CanIgnoreReturnValue // to skip a line public String readLine() throws IOException { while (lines.peek() == null) { - cbuf.clear(); + Java8Compatibility.clear(cbuf); // The default implementation of Reader#read(CharBuffer) allocates a // temporary char[], so we call Reader#read(char[], int, int) instead. int read = (reader != null) ? reader.read(buf, 0, buf.length) : readable.read(cbuf); diff --git a/guava/src/com/google/common/io/ReaderInputStream.java b/guava/src/com/google/common/io/ReaderInputStream.java index 9cbca93b8e93..eeb64e4e0d8c 100644 --- a/guava/src/com/google/common/io/ReaderInputStream.java +++ b/guava/src/com/google/common/io/ReaderInputStream.java @@ -104,7 +104,7 @@ final class ReaderInputStream extends InputStream { encoder.reset(); charBuffer = CharBuffer.allocate(bufferSize); - charBuffer.flip(); + Java8Compatibility.flip(charBuffer); byteBuffer = ByteBuffer.allocate(bufferSize); } @@ -143,7 +143,7 @@ public int read(byte[] b, int off, int len) throws IOException { return (totalBytesRead > 0) ? totalBytesRead : -1; } draining = false; - byteBuffer.clear(); + Java8Compatibility.clear(byteBuffer); } while (true) { @@ -189,8 +189,8 @@ public int read(byte[] b, int off, int len) throws IOException { private static CharBuffer grow(CharBuffer buf) { char[] copy = Arrays.copyOf(buf.array(), buf.capacity() * 2); CharBuffer bigger = CharBuffer.wrap(copy); - bigger.position(buf.position()); - bigger.limit(buf.limit()); + Java8Compatibility.position(bigger, buf.position()); + Java8Compatibility.limit(bigger, buf.limit()); return bigger; } @@ -207,7 +207,7 @@ private void readMoreChars() throws IOException { if (availableCapacity(charBuffer) == 0) { if (charBuffer.position() > 0) { // (2) There is room in the buffer. Move existing bytes to the beginning. - charBuffer.compact().flip(); + Java8Compatibility.flip(charBuffer.compact()); } else { // (3) Entire buffer is full, need bigger buffer. charBuffer = grow(charBuffer); @@ -220,7 +220,7 @@ private void readMoreChars() throws IOException { if (numChars == -1) { endOfInput = true; } else { - charBuffer.limit(limit + numChars); + Java8Compatibility.limit(charBuffer, limit + numChars); } } @@ -235,7 +235,7 @@ private static int availableCapacity(Buffer buffer) { * overflow must be due to a small output buffer. */ private void startDraining(boolean overflow) { - byteBuffer.flip(); + Java8Compatibility.flip(byteBuffer); if (overflow && byteBuffer.remaining() == 0) { byteBuffer = ByteBuffer.allocate(byteBuffer.capacity() * 2); } else {