Skip to content

Commit 21c91bd

Browse files
committed
JAVA-2559: Cast java.nio.ByteBuffer instances where necessary to java.nio.Buffer to avoid NoSuchMethodError when running on Java 6 to Java 8
The Java 9 ByteBuffer classes introduces overloaded methods with covariant return types for the following methods used by the driver: * position * limit * flip * clear Without casting, exceptions like this are thrown when executing on Java 8 and lower: java.lang.NoSuchMethodError: java.nio.ByteBuffer.limit(I)Ljava/nio/ByteBuffer This is because the generated byte code includes the static return type of the method, which is not found on Java 8 and lower because the overloaded methods with covariant return types don't exist.
1 parent f02a778 commit 21c91bd

File tree

9 files changed

+29
-20
lines changed

9 files changed

+29
-20
lines changed

bson/src/main/org/bson/ByteBufNIO.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.bson;
1818

19+
import java.nio.Buffer;
1920
import java.nio.ByteBuffer;
2021
import java.nio.ByteOrder;
2122
import java.util.concurrent.atomic.AtomicInteger;
@@ -98,7 +99,7 @@ public ByteBuf put(final byte b) {
9899

99100
@Override
100101
public ByteBuf flip() {
101-
buf.flip();
102+
((Buffer) buf).flip();
102103
return this;
103104
}
104105

@@ -114,13 +115,13 @@ public int limit() {
114115

115116
@Override
116117
public ByteBuf position(final int newPosition) {
117-
buf.position(newPosition);
118+
((Buffer) buf).position(newPosition);
118119
return this;
119120
}
120121

121122
@Override
122123
public ByteBuf clear() {
123-
buf.clear();
124+
((Buffer) buf).clear();
124125
return this;
125126
}
126127

@@ -202,7 +203,7 @@ public int position() {
202203

203204
@Override
204205
public ByteBuf limit(final int newLimit) {
205-
buf.limit(newLimit);
206+
((Buffer) buf).limit(newLimit);
206207
return this;
207208
}
208209

driver-async/src/main/com/mongodb/async/client/gridfs/GridFSBucketImpl.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.bson.types.ObjectId;
4141

4242
import java.io.IOException;
43+
import java.nio.Buffer;
4344
import java.nio.ByteBuffer;
4445

4546
import static com.mongodb.assertions.Assertions.notNull;
@@ -378,7 +379,7 @@ public void onResult(final GridFSFile result, final Throwable t) {
378379

379380
private void readAndWriteInputStream(final AsyncInputStream source, final GridFSUploadStream uploadStream, final ByteBuffer buffer,
380381
final SingleResultCallback<Void> callback) {
381-
buffer.clear();
382+
((Buffer) buffer).clear();
382383
source.read(buffer, new SingleResultCallback<Integer>() {
383384
@Override
384385
public void onResult(final Integer result, final Throwable t) {
@@ -398,7 +399,7 @@ public void onResult(final Void result, final Throwable abortException) {
398399
callback.onResult(null, t);
399400
}
400401
} else if (result > 0) {
401-
buffer.flip();
402+
((Buffer) buffer).flip();
402403
uploadStream.write(buffer, new SingleResultCallback<Integer>() {
403404
@Override
404405
public void onResult(final Integer result, final Throwable t) {
@@ -418,14 +419,14 @@ public void onResult(final Integer result, final Throwable t) {
418419

419420
private void readAndWriteOutputStream(final AsyncOutputStream destination, final GridFSDownloadStream downloadStream,
420421
final ByteBuffer buffer, final long amountRead, final SingleResultCallback<Long> callback) {
421-
buffer.clear();
422+
((Buffer) buffer).clear();
422423
downloadStream.read(buffer, new SingleResultCallback<Integer>() {
423424
@Override
424425
public void onResult(final Integer readResult, final Throwable t) {
425426
if (t != null) {
426427
callback.onResult(null, t);
427428
} else if (readResult > 0) {
428-
buffer.flip();
429+
((Buffer) buffer).flip();
429430
destination.write(buffer, new SingleResultCallback<Integer>() {
430431
@Override
431432
public void onResult(final Integer writeResult, final Throwable t) {

driver-async/src/main/com/mongodb/async/client/gridfs/helpers/AsyncStreamHelper.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import java.io.InputStream;
2525
import java.io.OutputStream;
26+
import java.nio.Buffer;
2627
import java.nio.ByteBuffer;
2728

2829
import static org.bson.assertions.Assertions.notNull;
@@ -209,9 +210,9 @@ private static void transferDataFromByteBuffers(final ByteBuffer srcByteBuffer,
209210
int transferAmount = Math.min(dstByteBuffer.remaining(), srcByteBuffer.remaining());
210211
if (transferAmount > 0) {
211212
ByteBuffer temp = srcByteBuffer.duplicate();
212-
temp.limit(temp.position() + transferAmount);
213+
((Buffer) temp).limit(temp.position() + transferAmount);
213214
dstByteBuffer.put(temp);
214-
srcByteBuffer.position(srcByteBuffer.position() + transferAmount);
215+
((Buffer) srcByteBuffer).position(srcByteBuffer.position() + transferAmount);
215216
}
216217
callback.onResult(transferAmount, null);
217218
}

driver-core/src/main/com/mongodb/connection/CompositeByteBuf.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.bson.ByteBuf;
2020

21+
import java.nio.Buffer;
2122
import java.nio.ByteBuffer;
2223
import java.nio.ByteOrder;
2324
import java.util.ArrayList;
@@ -255,7 +256,7 @@ public ByteBuf duplicate() {
255256
public ByteBuffer asNIO() {
256257
if (components.size() == 1) {
257258
ByteBuffer byteBuffer = components.get(0).buffer.asNIO().duplicate();
258-
byteBuffer.position(position).limit(limit);
259+
((Buffer) byteBuffer).position(position).limit(limit);
259260
return byteBuffer;
260261
} else {
261262
byte[] bytes = new byte[remaining()];

driver-core/src/main/com/mongodb/internal/connection/PowerOfTwoBufferPool.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.bson.ByteBuf;
2121
import org.bson.ByteBufNIO;
2222

23+
import java.nio.Buffer;
2324
import java.nio.ByteBuffer;
2425
import java.nio.ByteOrder;
2526
import java.util.HashMap;
@@ -75,8 +76,8 @@ public ByteBuf getBuffer(final int size) {
7576
ConcurrentPool<ByteBuffer> pool = powerOfTwoToPoolMap.get(log2(roundUpToNextHighestPowerOfTwo(size)));
7677
ByteBuffer byteBuffer = (pool == null) ? createNew(size) : pool.get();
7778

78-
byteBuffer.clear();
79-
byteBuffer.limit(size);
79+
((Buffer) byteBuffer).clear();
80+
((Buffer) byteBuffer).limit(size);
8081
return new PooledByteBufNIO(byteBuffer);
8182
}
8283

driver-core/src/test/unit/com/mongodb/connection/MessageHelper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.bson.io.OutputBuffer;
3030
import org.bson.json.JsonReader;
3131

32+
import java.nio.Buffer;
3233
import java.nio.ByteBuffer;
3334
import java.nio.ByteOrder;
3435

@@ -75,7 +76,7 @@ private static ReplyHeader buildReplyHeader(final int responseTo, final int numD
7576
headerByteBuffer.putLong(0); // cursorId
7677
headerByteBuffer.putInt(0); // startingFrom
7778
headerByteBuffer.putInt(numDocuments); //numberReturned
78-
headerByteBuffer.flip();
79+
((Buffer) headerByteBuffer).flip();
7980

8081
ByteBufNIO buffer = new ByteBufNIO(headerByteBuffer);
8182
return new ReplyHeader(buffer, new MessageHeader(buffer, getDefaultMaxMessageSize()));

driver-core/src/test/unit/com/mongodb/connection/ReplyMessageTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.bson.Document;
2222
import org.junit.Test;
2323

24+
import java.nio.Buffer;
2425
import java.nio.ByteBuffer;
2526
import java.nio.ByteOrder;
2627

@@ -42,7 +43,7 @@ public void shouldThrowExceptionIfRequestIdDoesNotMatchResponseTo() {
4243
headerByteBuffer.putLong(0);
4344
headerByteBuffer.putInt(0);
4445
headerByteBuffer.putInt(0);
45-
headerByteBuffer.flip();
46+
((Buffer) headerByteBuffer).flip();
4647

4748
ByteBufNIO byteBuf = new ByteBufNIO(headerByteBuffer);
4849
ReplyHeader replyHeader = new ReplyHeader(byteBuf, new MessageHeader(byteBuf, getDefaultMaxMessageSize()));
@@ -63,7 +64,7 @@ public void shouldThrowExceptionIfOpCodeIsIncorrect() {
6364
headerByteBuffer.putLong(0);
6465
headerByteBuffer.putInt(0);
6566
headerByteBuffer.putInt(0);
66-
headerByteBuffer.flip();
67+
((Buffer) headerByteBuffer).flip();
6768

6869
ByteBufNIO byteBuf = new ByteBufNIO(headerByteBuffer);
6970
ReplyHeader replyHeader = new ReplyHeader(byteBuf, new MessageHeader(byteBuf, getDefaultMaxMessageSize()));

driver-core/src/test/unit/com/mongodb/connection/TestInternalConnection.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.bson.io.BsonInput;
2828
import org.bson.io.ByteBufferBsonInput;
2929

30+
import java.nio.Buffer;
3031
import java.nio.ByteBuffer;
3132
import java.nio.ByteOrder;
3233
import java.util.Deque;
@@ -124,7 +125,7 @@ public void sendMessage(final List<ByteBuf> byteBuffers, final int lastRequestId
124125
combined.put(buf.array(), 0, buf.remaining());
125126
}
126127

127-
combined.flip();
128+
((Buffer) combined).flip();
128129

129130
Interaction interaction = replies.getFirst();
130131
if (interaction.responseBuffers != null) {
@@ -190,7 +191,7 @@ private ReplyHeader replaceResponseTo(final ReplyHeader header, final int respon
190191
headerByteBuffer.putLong(header.getCursorId());
191192
headerByteBuffer.putInt(header.getStartingFrom());
192193
headerByteBuffer.putInt(header.getNumberReturned());
193-
headerByteBuffer.flip();
194+
((Buffer) headerByteBuffer).flip();
194195

195196
ByteBufNIO buffer = new ByteBufNIO(headerByteBuffer);
196197
MessageHeader messageHeader = new MessageHeader(buffer, ConnectionDescription.getDefaultMaxMessageSize());

driver/src/main/org/bson/LazyBSONObject.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import java.io.IOException;
3131
import java.io.OutputStream;
32+
import java.nio.Buffer;
3233
import java.nio.ByteBuffer;
3334
import java.nio.ByteOrder;
3435
import java.nio.channels.Channels;
@@ -261,8 +262,8 @@ BsonBinaryReader getBsonReader() {
261262
private ByteBuffer getBufferForInternalBytes() {
262263
ByteBuffer buffer = ByteBuffer.wrap(bytes, offset, bytes.length - offset).slice();
263264
buffer.order(ByteOrder.LITTLE_ENDIAN);
264-
buffer.limit(buffer.getInt());
265-
buffer.rewind();
265+
((Buffer) buffer).limit(buffer.getInt());
266+
((Buffer) buffer).rewind();
266267
return buffer;
267268
}
268269

0 commit comments

Comments
 (0)