Jetty.project: NoSuchMethodError: java.nio.ByteBuffer.limit(I)Ljava/nio/ByteBuffer

Created on 8 Jan 2019  Â·  10Comments  Â·  Source: eclipse/jetty.project

Like many other projects (Tomcat, MongoDB, etc.) compiling with JDK 9+ with release 8 produces incorrect bytecode for these ByteBuffer methods:

position(int)
limit(int)
mark​()
reset​()
clear()
flip()
rewind​()

Running a Jetty compiled with JDK 9+ with release 8 in a JDK 8 JVM will produce a NoSuchMethodError.

The solution is to cast the ByteBuffer to Buffer when calling those methods:

((Buffer)byteBuffer).position(0);
Bug Build Help Wanted Java 11

Most helpful comment

Sorry to butt in here, but I see this and several other projects adding unnecessary casts for this issue. I have never seen javac produce the wrong bytecodes when given the proper --release flag. The wrong bytecodes issue seems to occur when one is using (for example) JDK 9 and using "javac -source 8 -target 8", which does let Java 9 library dependencies leak into Java 8 classes (and which issues a warning) and which results in this problem. Usually the problem seems to be that something in the build system is still using the -source 8 -target 8 technique and thus the problem persists.

Now if javac --release 8 is still letting Java 9 dependencies into the Java 8 class files, that's a bug and we should fix it.

All 10 comments

To be clear this is because Java 9 introduced a Covariant return type that when compiled with Java 9+ includes the return type in the (jetty) bytecode, rendering the bytecode incompatible with Java 8.
Right?

@joakime correct.

The call byteBuffer.position(0) in JDK 8 calls method Buffer.position(I)LBuffer while in JDK 9+ calls method ByteBuffer.position(I)LByteBuffer.
When a JVM 8 sees the latter it does not find it, hence the error.

I'm still astonished that JDK 9's javac produces the wrong bytecode even when specifying --release 8.

REALLY??? ugh!
But should be a simple fix if we have all been using BufferUtil like we should be :)

However, we don't want to "fix" this in jetty-10 as that is never intended to be run on java8, so do we just need to fix this in jetty-9?

@gregw, correct we only need it in 9.4.x.

I also run into this problem, any update upon this ?

@DreamWuGit to work around, in your project, compile with JDK8, run with any JDK.

@joakime but the problem is that Maven Central artifacts that we produce are compiled with JDK 9+.

Sorry to butt in here, but I see this and several other projects adding unnecessary casts for this issue. I have never seen javac produce the wrong bytecodes when given the proper --release flag. The wrong bytecodes issue seems to occur when one is using (for example) JDK 9 and using "javac -source 8 -target 8", which does let Java 9 library dependencies leak into Java 8 classes (and which issues a warning) and which results in this problem. Usually the problem seems to be that something in the build system is still using the -source 8 -target 8 technique and thus the problem persists.

Now if javac --release 8 is still letting Java 9 dependencies into the Java 8 class files, that's a bug and we should fix it.

@stuart-marks I just double checked this and you are right, --release 8 produces the right bytecode.

We do have a profile that is automatically enabled when compiling with JDK > 8 (https://github.com/eclipse/jetty.project/blob/jetty-9.4.18.v20190429/pom.xml#L1843) that enforces --release 8 so we should be good.

Thank you, @sbordet. I'm new to Java and your comment helped me fix the issue quickly!

Was this page helpful?
0 / 5 - 0 ratings