Conversation
pavolloffay
left a comment
There was a problem hiding this comment.
we should start testing against JVM 8 and 11. Can you file a ticket for it?
Agreed, but this is definitely an interesting one as this code compiles and works properly when compiled and run on 1.8, just not when it was compiled with 11 and run on 1.8. I think we'd want to leverage gradle's support for toolchains to register a test task that uses a different jvm to run the tests than the one used to compile the instrumentation module. Did you have an idea of how this might look? |
|
We should be building with Java 11 and using |
|
Yeah that makes sense, I'm just curious if you had any other ideas for how that might be implemented in practice. The simplest option (to me) would seem to be using the GitHub actions |
|
Moving the conversation about cross JRE testing to #335 |
Use --release flag to target JDK 8 bytecode compatibility
My recent change to capture HTTP requests contained a fascinating bug resulting in the bug-fix not working when running on JVMs <= 1.8 due to a
NoSuchMethodErrorbeing thrown when this line executes. This was incredibly surprising to me, because theposition(int)API exists onBuffer(the superclass ofByteBuffer) in java 1.8, so why do we have problems here? Confused, I did a quick google search and found an incredibly helpful article right away: ByteBuffer and the Dreaded NoSuchMethodError. The tl;dr of this change is that, the bytecode we produce prior to this change looked like this:BEFORE
AFTER
Spot the difference? The bytecode for this snippet is identical, but when compiled without the
--release 8, theinvokevirtual #24call refers to a method reference in the constant pool with a signature matching the descriptorMethod java/nio/ByteBuffer.position:(I)Ljava/nio/ByteBuffer. However, when we compile it with the--release 8flag the method reference in the constant pool isMethod java/nio/ByteBuffer.position:(I)Ljava/nio/Buffer. This resolves the cross-jre compatibility issue of using theByteBuffer.position(int)API becauseMethod java/nio/ByteBuffer.position:(I)Ljava/nio/ByteBufferdoes not exist on JDK 1.8 or below.Other notes
It's worth noting that this has impacted many well-known open source projects. The blog i linked above links to several other projects that encountered this exact issue:
The author also evaluated other methods of resolving this issue and verifying that it couldn't happen again, and determined the
--releaseflag was the best option: