-
Notifications
You must be signed in to change notification settings - Fork 112
Description
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.UpgradeToJava17For a source file marked as Java 21:
- Expected:
String.format("%s %s", "hello", "world")→"%s %s".formatted("hello", "world")(sinceStringFormattedchecksUsesJavaVersion(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
Type
Projects
Status