Stop shadowing Task._stop and Task._lastException (CodeQL java/field-masks-super-field)#238
Open
vharseko wants to merge 3 commits into
Open
Conversation
…masks-super-field)
StreamLoader and StreamSaver each redeclared _stop and _lastException, which are
already declared in their superclass Task. The shadowing meant the two classes
did not share the base fields, breaking the Task framework's contract:
- Task._stop is an AtomicBoolean that Task.stop() sets to request cancellation,
but StreamSaver declared its own boolean _stop that nothing ever set, so its
save loops (saveAll / saveTrees / the traversal loop) never observed a stop
request and could not be cancelled. Remove the shadow field and test the
inherited AtomicBoolean via _stop.get().
- Task._lastException is the field Task reports through the task status, but
StreamSaver recorded failures into its own shadow copy, so the reported
status stayed "none". Remove the shadow so the recorded exception reaches the
status.
- StreamLoader's _stop and _lastException were shadow fields that were never
read or written, so they are simply removed.
For a normal (non-cancelled) run _stop is false throughout, so the save loops
behave exactly as before; the change only lets a cancellation actually take
effect and lets the recorded exception surface in the task status.
…short-circuit-evaluation) The save loops combined the traversal/index test with the stop flag using the non-short-circuit & operator. The right operand (!_stop.get()) has no side effects and the left operand is always evaluated first, so switching to && is behaviour-preserving and avoids the redundant _stop.get() once the loop condition's left side is already false.
maximthomas
approved these changes
Jul 9, 2026
180b72e to
85fbaba
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Addresses the
java/field-masks-super-fieldalerts inStreamLoaderandStreamSaver. Both classes extendTaskand redeclared_stopand_lastException, whichTaskalready declares, so the subclasses shadowed thebase fields instead of sharing them — a real defect, not just style.
StreamSaver.java_stop(boolean)Task._stop(AtomicBoolean)StreamSaver.java_lastExceptionTask._lastExceptionStreamLoader.java_stop,_lastExceptionTask._stop,Task._lastExceptionDetails
StreamSaver._stop—Task._stopis anAtomicBooleanthatTask.stop()flips to request cancellation.
StreamSaver's ownboolean _stopwas neverassigned, so
saveAll,saveTreesand the traversal loop kept running evenafter a stop was requested. The shadow is removed and the loops now test the
inherited
_stop.get().StreamSaver._lastException—Taskreports_lastExceptionin the taskstatus;
StreamSaverwrote its own copy, so the status stayednone. Removingthe shadow lets the recorded exception surface.
StreamLoader— its_stop/_lastExceptionwere never read or written,so they are just removed.
For a normal (non-cancelled) run
_stopisfalsethroughout, so the loopsbehave exactly as before; the change only lets a cancellation take effect and the
recorded exception appear in the task status.
Not changed here
The two remaining alerts on
InstallExternalDependencyMojo.installerandAbstractExternalDependencyMojo.artifactFactoryare intentional: these areMaven 2
@componentfields re-declared in the plugin's own source so theQDox-based plugin-descriptor generator emits the Plexus injection requirement
(the base classes live in compiled Maven artifacts whose
@componenttags thegenerator cannot see). Removing them would drop the injection and NPE at runtime,
so they are left as-is.
Testing
mvn -o -pl persistit/core compile— BUILD SUCCESS.