Skip to content

Initialize ScanningRecipe accumulator key eagerly for thread safety#6914

Merged
pstreef merged 1 commit intoopenrewrite:mainfrom
pstreef:fix/scanning-recipe-thread-safe-uuid
Mar 16, 2026
Merged

Initialize ScanningRecipe accumulator key eagerly for thread safety#6914
pstreef merged 1 commit intoopenrewrite:mainfrom
pstreef:fix/scanning-recipe-thread-safe-uuid

Conversation

@pstreef
Copy link
Copy Markdown
Contributor

@pstreef pstreef commented Mar 10, 2026

Problem

ScanningRecipe.recipeAccMessage uses lazy initialization that is not thread-safe:

@Nullable
private String recipeAccMessage;

private String getRecipeAccMessage() {
    if (recipeAccMessage == null) {
        recipeAccMessage = "org.openrewrite.recipe.acc." + UUID.randomUUID();
    }
    return recipeAccMessage;
}

When recipe instances are shared across concurrent runs, two threads can see null simultaneously, generate different UUIDs, and one overwrites the other. The losing thread's accumulator data — stored under the now-orphaned UUID — becomes unreachable.

Solution

Change to eager initialization at field declaration. The UUID generation cost is negligible and the field is always used, so lazy init provided no benefit. The clone() method continues to assign a new UUID as before.

The recipeAccMessage field used lazy initialization that was not
thread-safe. If two concurrent recipe runs accessed the same shared
ScanningRecipe instance before initialization, both threads could
generate different UUIDs, causing one thread's accumulator data to
be stored under a key that gets overwritten.

Change to eager initialization at field declaration, which is
inherently thread-safe since the JVM guarantees constructor
completion before the object is visible to other threads.
@github-project-automation github-project-automation Bot moved this to In Progress in OpenRewrite Mar 10, 2026
@pstreef pstreef changed the title Initialize ScanningRecipe accumulator key eagerly for thread safety Fix thread-safety issues in ScanningRecipe and DeclarativeRecipe accumulator handling Mar 10, 2026
@pstreef pstreef marked this pull request as draft March 10, 2026 16:06
@pstreef pstreef force-pushed the fix/scanning-recipe-thread-safe-uuid branch from 601bcea to 9a2690b Compare March 11, 2026 08:43
@pstreef pstreef changed the title Fix thread-safety issues in ScanningRecipe and DeclarativeRecipe accumulator handling Initialize ScanningRecipe accumulator key eagerly for thread safety Mar 11, 2026
@pstreef pstreef marked this pull request as ready for review March 11, 2026 09:10
@github-project-automation github-project-automation Bot moved this from In Progress to Ready to Review in OpenRewrite Mar 16, 2026
@pstreef pstreef merged commit c22f89b into openrewrite:main Mar 16, 2026
2 checks passed
@github-project-automation github-project-automation Bot moved this from Ready to Review to Done in OpenRewrite Mar 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants