fix: migrate spec POJOs to AtomicReference + immutable snapshots (S3077)#423
Open
fix: migrate spec POJOs to AtomicReference + immutable snapshots (S3077)#423
Conversation
Contributor
Author
|
@eskenazit This will need to be rebased on main once PR #420 is merged |
This was referenced May 6, 2026
Resolves SonarQube rule java:S3077 (Non-thread-safe fields should not be volatile) across 27 spec POJO classes (44 bug occurrences). Each volatile field is replaced with an AtomicReference / AtomicBoolean / AtomicInteger holding an immutable snapshot for collections (List.copyOf / Map.copyOf). Adds SpecFieldThreadSafetyTest as a structural meta-test that fails if any covered class re-introduces volatile, guarding against regression. Phase 2 of sonar-bug-remediation. Closes #422.
06ea1c1 to
4ac2dd9
Compare
Contributor
Author
|
Rebased onto This branch was originally cut from Result:
|
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.
Related Issue
Closes #422
What does this PR do?
Phase 2 of
sonar-bug-remediation. Resolves SonarQube rulejava:S3077— "Non-thread-safe fields should not bevolatile" — across 27 spec POJO classes (44 bug occurrences from run #1516, plus surrounding non-flaggedvolatilefields on the same classes for consistency).Each
volatilefield is replaced with anAtomicReference<T>(orAtomicBoolean/AtomicIntegerfor primitive cases) holding an immutable snapshot for collections (List.copyOf/Map.copyOf). This:volatileremains on any non-thread-safe type.set/updateAndGet.String/List<T>/Map<K,V>. Jackson never sees anAtomicReference.Patterns applied (documented in the blueprint):
String,Integer, custom Spec):AtomicReference<T>with plain getter/setter.List<T>: stored asList.copyOf(...)snapshot orCopyOnWriteArrayListinside anAtomicReference.Map<K, V>: stored asMap.copyOf(...)snapshot inside anAtomicReference.setParameter-style mutations useupdateAndGetfor lock-free copy-on-write.Lazy initializers (e.g.
ControlServerSpec.getManagement(),ObservabilityMetricsSpec.getLocal(),ControlManagementSpec.getLogs()) now usecompareAndSetto remain thread-safe.Files migrated (27)
io.naftiko.specNaftikoSpec,OperationSpecio.naftiko.spec.aggregatesAggregateSpec,AggregateFunctionSpecio.naftiko.spec.consumes.httpHttpClientSpec,HttpClientResourceSpec,HttpClientOperationSpec,OAuth2AuthenticationSpecio.naftiko.spec.exposesServerSpec,ServerCallSpecio.naftiko.spec.exposes.controlControlServerSpec,ControlManagementSpecio.naftiko.spec.exposes.mcpMcpServerToolSpec,McpServerResourceSpecio.naftiko.spec.exposes.restRestServerOperationSpec,RestServerResourceSpec,RestServerStepSpecio.naftiko.spec.exposes.skillExposedSkillSpec,SkillToolSpecio.naftiko.spec.observabilityObservabilitySpec,ObservabilityMetricsSpec,ObservabilityTracesSpec,ObservabilityExportersSpecio.naftiko.spec.scriptingOperationStepScriptSpecio.naftiko.spec.utilBindingSpec,OperationStepCallSpec,StructureSpecEngine-layer classes (Phase 3) and
char[]auth password fields (Phase 4) are tracked separately.Note on PR ordering
This branch was cut from
fix/sonar-major-bugs(Phase 1, PR #420) but the two phases touch disjoint files, so this PR can be reviewed independently. Once #420 merges, this branch will be rebased ontomain.Tests
New test
SpecFieldThreadSafetyTest— a structural meta-test that uses reflection to verify:volatilefield (guards against S3077 regression).This test would have failed 26 times before the migration (every class except
ObservabilityExportersSpecalready migrated as the canonical proof-of-pattern), proving the fix is real.Existing tests
The existing extensive Jackson round-trip and engine-wiring suite (
ObservabilitySpecTest,TelemetryBootstrapTest,BindingSpecTest,InputParameterRoundTripTest, etc.) continues to pass — confirming that Jackson sees no behavioural difference and the engine reads values correctly through the new accessor shape.Full test results
The 14 failures are pre-existing and unrelated to this change — they affect
Step{2-8,10}Shipyard*IntegrationTestand stem from non-deterministic LLM responses (the model occasionally returns prose like "The …" instead of JSON, triggeringUnrecognized token 'The'). These were already failing onmainbefore this PR.Checklist
mvn testshows 963 / 977 passing — only pre-existing LLM flakiness fails)main(will rebase after fix: resolve MAJOR Sonar bugs in HttpClientAdapter and OasImportConverter #420 merges)Agent Context