Skip to content

Singleton precondition on UpgradeToJava17 breaks StringFormatted when nested under multiple HasJavaVersion contexts #982

@honnix

Description

@honnix

Summary

After upgrading from rewrite-migrate-java 3.26.0 to 3.27.0, the StringFormatted recipe within UpgradeToJava17 no longer converts String.format() to String.formatted() when the recipe is reached through a Java 21 precondition context — but still works correctly through a Java 17 precondition context.

Root cause

The commit 6e525a15 ("Make declarative recipes singletons") added org.openrewrite.Singleton as a precondition to UpgradeToJava17. This breaks when UpgradeToJava17 appears under multiple HasJavaVersion precondition contexts in a composite recipe.

Reproduction

Given this recipe structure:

# Parent recipe
recipeList:
  - com.example.Java21Conventions
  - com.example.Java17Conventions

---
name: com.example.Java21Conventions
preconditions:
  - org.openrewrite.java.search.HasJavaVersion:
      version: 21
recipeList:
  - org.openrewrite.java.migrate.UpgradeToJava17

---
name: com.example.Java17Conventions
preconditions:
  - org.openrewrite.java.search.HasJavaVersion:
      version: 17
recipeList:
  - org.openrewrite.java.migrate.UpgradeToJava17

For a source file marked as Java 21:

  • Expected: String.format("%s %s", "hello", "world")"%s %s".formatted("hello", "world") (since StringFormatted checks UsesJavaVersion(17) which matches Java 21)
  • Actual: String.format(...) is left unchanged

For a source file marked as Java 17:

  • Works correctly: String.format(...)"...".formatted(...)

Analysis

The StringFormatted recipe itself has not changed between 3.26.0 and 3.27.0 — its visitor correctly uses UsesJavaVersion(17) which should match Java 21+. The only change is the addition of Singleton to UpgradeToJava17.

This suggests the Singleton precondition interacts incorrectly with nested precondition contexts when the same recipe appears in multiple branches of a composite recipe tree.

Versions

  • rewrite-migrate-java: 3.27.0 (works in 3.26.0)
  • rewrite-java: 8.73.0

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingrecipeRecipe requested

Type

Projects

Status

Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions