[Fix][Engine] Fix JDK 8 NoSuchMethodError in StainTracePayload#append - #10994
Conversation
ByteBuffer.position(int) was overridden with a covariant ByteBuffer return type in JDK 9+. When code compiled on JDK 9+ runs on JDK 8, the JVM cannot find ByteBuffer.position(I)LByteBuffer; and throws NoSuchMethodError. Cast to the Buffer superclass so the call resolves to Buffer.position(I)LBuffer; which is present on JDK 8. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
+1 good job🚀 |
DanielLeens
left a comment
There was a problem hiding this comment.
Thanks for working on this. I reviewed the latest head from scratch and checked the exact binary-payload append path that runs when stain-trace sampling records another stage hop.
What this PR solves
- User pain: on JDK 8,
StainTracePayload.append(...)can hitNoSuchMethodErrorbecause the compiled call targets the JDK 9+ covariantByteBuffer.position(int)signature instead of the JDK 8Buffer.position(int)signature. - Fix approach: cast the wrapped buffer to
Bufferbefore callingposition(int), so the call binds to the JDK 8-compatible superclass method. - One-line summary: this is a precise compatibility fix on the real payload-append hot path, and I did not find a new source-level blocker.
Runtime path I checked
sampled row trace path
-> StainTracePayload.append(...) [81-101]
-> validate payload
-> expand byte array
-> move write cursor to old payload length
-> append stage code / task ID / timestamp
-> update entry count
Review result
StainTracePayload.java:90-100is exactly the right place to fix this.- The new cast at
StainTracePayload.java:92-96is minimal and targeted: it preserves the existing binary layout while avoiding the JDK 8 linkage problem. - I did not see a reopened compatibility or payload-corruption risk from this change.
Tests / CI
- The code change is very small and the compatibility rationale is clear from the in-code comment.
- The current apache-side
Buildcheck is red, but the corresponding fork Actions run I inspected is still in progress and has not yet produced a clean final PR-specific failure diagnosis. So I am not treating that red badge as source evidence against this fix.
Conclusion: can merge after fixes
- Blocking items
- No source-level blocker from my side on the latest head.
- Please make sure the branch ends up with one valid CI result before merge, because the current public
Buildbadge is not a trustworthy final signal yet.
- Suggested non-blocking follow-up
- None from my side on this code path.
From the code-review side, the JDK 8 compatibility fix itself looks good.
DanielLeens
left a comment
There was a problem hiding this comment.
Thanks for the update. I re-checked the latest head from scratch, including the original JDK 8 compatibility fix and the new workflow adjustment.
What this PR fixes:
- User pain:
StainTracePayload.append(...)can hitNoSuchMethodErroron JDK 8. - Fix approach: bind the append path to the JDK 8-compatible
Buffer.position(int)call; the latest head also increases the Kudu E2E workflow timeout to match real template fan-out. - One-line summary: the code fix still looks correct, and the newest workflow delta is aligned with the CI symptom rather than masking a code problem.
Runtime path re-checked:
StainTracePayload.append(...)
-> move buffer cursor
-> append stage/task/timestamp bytes
Findings:
- No blocking source-level issue on the current head.
- The production compatibility fix remains correct on
StainTracePayload.java:90-96. - The latest delta in
.github/workflows/backend.yml:1240simply increases the Kudu E2E timeout from 60 to 90 minutes, which matches the expanded template load.
CI:
statusCheckRollupstill shows an old failingBuildcheck-run, buthead_sha=e6b2ad3...maps to the latest Apache workflow runs and both are successful.
Conclusion: can merge
- Blocking items
- None.
- Suggested follow-up
- None.
Overall, this is mergeable.
DanielLeens
left a comment
There was a problem hiding this comment.
Thanks for the update. I re-reviewed the latest head from scratch, including the original JDK 8 compatibility fix and the new Pulsar E2E / workflow follow-up commits.
What this PR solves
- User pain: once stain-trace sampling hits,
StainTracePayload.append(...)runs on the real source/transform/sink trace path. On JDK 8, a directByteBuffer.position(int)call can link to the JDK 9+ covariant signature and fail at runtime withNoSuchMethodError. - Fix approach: the latest head binds that cursor move to
Buffer.position(int)via((Buffer) buffer).position(...), while keeping the payload binary layout unchanged. - One-line summary: this is still a precise compatibility fix on the real hot path, and I did not find a new source-level blocker in the latest head.
Runtime path I checked
sampled row trace path
-> SeaTunnelSourceCollector.tryStainTrace(...) [SeaTunnelSourceCollector.java:342-369]
-> StainTracePayload.init(...)
-> StainTracePayload.append(...) [StainTracePayload.java:81-101]
row continues through later stages
-> StainTraceUtils.tryAppendPayload(...) [StainTraceUtils.java:72-91]
-> StainTracePayload.append(...) again
Review result
StainTracePayload.java:90-96is exactly the right place to fix the JDK 8 linkage issue.- The
Buffercast keeps the on-wire payload format unchanged, so I do not see a serialization or compatibility regression here. - The new Pulsar E2E helper and test updates look structurally stable as well: no
Thread.sleep, no fixed-port assumptions, and the image pre-pull path has an explicit timeout.
CI
Buildis still running on the latest head at the time of this review, so I am not treating CI as a negative code signal right now.
Conclusion: can merge
- Blocking items
- None from my side on the current source changes.
- Suggested follow-up
- None.
From the code-review side, this latest head looks good to merge once the running CI finishes cleanly.
Purpose
Fix a JDK 8 runtime incompatibility in
StainTracePayload#append.Problem
In JDK 9+,
ByteBufferadded a covariant override ofBuffer.position(int)that returnsByteBufferinstead ofBuffer.When the project is compiled on JDK 9+ (which emits bytecode referencing
ByteBuffer.position(I)LByteBuffer;) and then run on JDK 8, the JVM cannot resolve that method descriptor and throws:The affected line is in
append():Fix
Cast to the
Buffersuperclass so the call always resolves toBuffer.position(I)LBuffer;, which exists on every JDK version:This is the standard idiom used throughout the JDK and many libraries to keep
ByteBuffercode compatible with JDK 8.Checklist
StainTracePayloadTest) pass