From 79bb7e224f6465a0cd23bc637c54bc587f31797b Mon Sep 17 00:00:00 2001 From: BoykoAlex Date: Fri, 24 Apr 2026 16:27:32 -0700 Subject: [PATCH 1/2] Scanning recipe for upgrading parent blows up --- .../maven/UpgradeParentVersionTest.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/UpgradeParentVersionTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/UpgradeParentVersionTest.java index 84dd58f249c..6f0be277f5b 100644 --- a/rewrite-maven/src/test/java/org/openrewrite/maven/UpgradeParentVersionTest.java +++ b/rewrite-maven/src/test/java/org/openrewrite/maven/UpgradeParentVersionTest.java @@ -25,7 +25,11 @@ import org.openrewrite.test.RewriteTest; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import static org.assertj.core.api.Assertions.assertThat; +import static org.openrewrite.java.Assertions.mavenProject; import static org.openrewrite.maven.Assertions.pomXml; class UpgradeParentVersionTest implements RewriteTest { @@ -302,4 +306,72 @@ void upgradeParentWithCIFriendlyVersionsAndNullProperty() { ) ); } + + @Test + void jacksonBomVersionRename() { + rewriteRun( + spec -> spec.recipes( + new RenamePropertyKey( + "jackson-bom.version", + "jackson-2-bom.version" + ), + new UpgradeParentVersion( + "org.springframework.boot", + "spring-boot-starter-parent", + "4.0.X", + null, + null)), + mavenProject("jackson-bom-rename-demo", + pomXml( + """ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.0 + + + com.example + demo + 0.0.1-SNAPSHOT + + 17 + 2.21.2 + + + """, + spec -> spec.after(pom -> { + Matcher version = Pattern.compile("spring-boot-starter-parent\\s*(4\\.0\\.\\d+(?:-[\\w\\.]+)?)").matcher(pom); + assertThat(version.find()).describedAs("Expected Spring Boot 4.0.x parent in %s", pom).isTrue(); + + //language=xml + return String.format(""" + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + %s + + + com.example + demo + 0.0.1-SNAPSHOT + + 17 + 2.21.2 + + + """, version.group(1)); + }) + ) + ) + ); + } + } From 72f24184e01f686308316deb290173d17670822c Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Tue, 26 May 2026 22:12:39 +0200 Subject: [PATCH 2/2] Make ChangeParentPom scan-time resolve best-effort The scanner's deep `ResolvedPom.resolve(...)` is brittle: the new parent's dependencyManagement is interpolated against the current pom's property map, which can fail when a property was renamed by a prior recipe or when the user's property value no longer fits the new parent. The failure was surfaced as a misleading warning marker on ``, even when the upgrade itself worked. Try the deep resolve so descendants can still see the new parent's managed dependencies. If it throws, fall back to a shallow updated marker that swaps in the new parent reference; each pom's `maybeUpdateModel` will re-resolve from the post-edit XML. --- .../openrewrite/maven/ChangeParentPom.java | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/ChangeParentPom.java b/rewrite-maven/src/main/java/org/openrewrite/maven/ChangeParentPom.java index f6ffeec4700..f2ce2bb2558 100755 --- a/rewrite-maven/src/main/java/org/openrewrite/maven/ChangeParentPom.java +++ b/rewrite-maven/src/main/java/org/openrewrite/maven/ChangeParentPom.java @@ -173,7 +173,6 @@ public Validated validate() { public static class Accumulator { @Nullable MavenResolutionResult updatedRootMarker; - @Nullable MavenDownloadingException scannerException; final Map gavToOriginalMarker = new HashMap<>(); final Map gavToNewMarker = new HashMap<>(); @@ -296,20 +295,33 @@ public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) { return document; } - // Pre-compute the updated MavenResolutionResult with the new parent info + // Pre-compute the updated MavenResolutionResult with the new parent info. + // Attempt a deep resolve so that descendant pom markers can reflect the new + // parent's dependencyManagement. If the deep resolve fails (for instance, + // the new parent's dependencyManagement references properties whose names or + // values only become valid after the visitor — or a prior recipe such as + // RenamePropertyKey — edits the XML), fall back to a shallow marker that + // just swaps in the new parent reference. Each pom's marker is re-resolved + // later by `maybeUpdateModel` once the XML edits land. Parent updatedParentRef = new Parent( new GroupArtifactVersion(targetGroupId, targetArtifactId, targetVersion.get()), targetRelativePath ); Pom updatedPom = mrr.getPom().getRequested().withParent(updatedParentRef); - ResolvedPom updatedResolvedPom = mrr.getPom() - .withRequested(updatedPom) - .resolve(ctx, new MavenPomDownloader( - mrr.getProjectPoms(), ctx, mrr.getMavenSettings(), mrr.getActiveProfiles())); + ResolvedPom updatedResolvedPom; + try { + updatedResolvedPom = mrr.getPom() + .withRequested(updatedPom) + .resolve(ctx, new MavenPomDownloader( + mrr.getProjectPoms(), ctx, mrr.getMavenSettings(), mrr.getActiveProfiles())); + } catch (MavenDownloadingException deepResolveFailure) { + updatedResolvedPom = mrr.getPom().withRequested(updatedPom); + } acc.updatedRootMarker = mrr.withPom(updatedResolvedPom); } - } catch (MavenDownloadingException e) { - acc.scannerException = e; + } catch (MavenDownloadingException ignored) { + // Metadata download failure for the new parent's version metadata — the + // visitor's own resolve will surface this as a warning on the parent tag. } } return document; @@ -466,9 +478,6 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) { } return e.warn(tag); } - if (acc.scannerException != null) { - t = acc.scannerException.warn(t); - } } } return t;