Set Java 8 release compiler option #334
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
NoSuchMethodError
being 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 #24
call 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 8
flag 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/ByteBuffer
does 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
--release
flag was the best option: