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; 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)); + }) + ) + ) + ); + } + }