diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index d998c730678..e0dfdcbf39b 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -39,7 +39,7 @@ dependencies { implementation("io.spring.javaformat:spring-javaformat-gradle-plugin:${javaFormatVersion}") implementation("io.spring.nohttp:nohttp-gradle:0.0.11") implementation("org.apache.httpcomponents.client5:httpclient5:5.3.1") - implementation("org.apache.maven:maven-embedder:${mavenVersion}") + implementation("org.apache.maven:maven-artifact:${mavenVersion}") implementation("org.antora:gradle-antora-plugin:1.0.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}") implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${kotlinVersion}") diff --git a/buildSrc/src/main/java/org/springframework/boot/build/MavenPublishingConventions.java b/buildSrc/src/main/java/org/springframework/boot/build/MavenPublishingConventions.java index 8bc2fb6efdb..28fd088bda3 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/MavenPublishingConventions.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/MavenPublishingConventions.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ package org.springframework.boot.build; -import org.apache.maven.artifact.repository.MavenArtifactRepository; import org.gradle.api.Project; +import org.gradle.api.artifacts.repositories.MavenArtifactRepository; import org.gradle.api.attributes.Usage; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginExtension; diff --git a/buildSrc/src/main/java/org/springframework/boot/build/mavenplugin/MavenPluginPlugin.java b/buildSrc/src/main/java/org/springframework/boot/build/mavenplugin/MavenPluginPlugin.java index ce576a1057d..6d61e6f0795 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/mavenplugin/MavenPluginPlugin.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/mavenplugin/MavenPluginPlugin.java @@ -17,10 +17,8 @@ package org.springframework.boot.build.mavenplugin; import java.io.File; -import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; -import java.io.InputStream; import java.io.Writer; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -28,16 +26,9 @@ import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.Arrays; import java.util.Properties; -import java.util.function.BiConsumer; +import java.util.Set; import javax.inject.Inject; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; import io.spring.javaformat.formatter.FileEdit; import io.spring.javaformat.formatter.FileFormatter; @@ -88,19 +79,18 @@ import org.gradle.api.tasks.TaskProvider; import org.gradle.api.tasks.bundling.Jar; import org.gradle.api.tasks.javadoc.Javadoc; import org.gradle.external.javadoc.StandardJavadocDocletOptions; -import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; import org.springframework.boot.build.DeployedPlugin; import org.springframework.boot.build.MavenRepositoryPlugin; +import org.springframework.boot.build.bom.ResolvedBom; +import org.springframework.boot.build.bom.ResolvedBom.ResolvedLibrary; import org.springframework.boot.build.optional.OptionalDependenciesPlugin; import org.springframework.boot.build.test.DockerTestPlugin; import org.springframework.boot.build.test.IntegrationTestPlugin; import org.springframework.core.CollectionFactory; -import org.springframework.util.Assert; /** * Plugin for building Spring Boot's Maven Plugin. @@ -125,7 +115,13 @@ public class MavenPluginPlugin implements Plugin { generateHelpMojoTask); addDocumentPluginGoalsTask(project, generatePluginDescriptorTask); addPrepareMavenBinariesTask(project); - addExtractVersionPropertiesTask(project); + TaskProvider extractVersionPropertiesTask = addExtractVersionPropertiesTask(project); + project.getTasks() + .named(IntegrationTestPlugin.INT_TEST_TASK_NAME) + .configure((task) -> task.getInputs() + .file(extractVersionPropertiesTask.map(ExtractVersionProperties::getDestination)) + .withPathSensitivity(PathSensitivity.RELATIVE) + .withPropertyName("versionProperties")); publishOptionalDependenciesInPom(project); project.getTasks().withType(GenerateModuleMetadata.class).configureEach((task) -> task.setEnabled(false)); } @@ -335,9 +331,9 @@ public class MavenPluginPlugin implements Plugin { return input.replace("{{version}}", project.getVersion().toString()); } - private void addExtractVersionPropertiesTask(Project project) { - project.getTasks().register("extractVersionProperties", ExtractVersionProperties.class, (task) -> { - task.setEffectiveBoms(project.getConfigurations().create("versionProperties")); + private TaskProvider addExtractVersionPropertiesTask(Project project) { + return project.getTasks().register("extractVersionProperties", ExtractVersionProperties.class, (task) -> { + task.setResolvedBoms(project.getConfigurations().create("versionProperties")); task.getDestination() .set(project.getLayout() .getBuildDirectory() @@ -466,16 +462,16 @@ public class MavenPluginPlugin implements Plugin { public abstract static class ExtractVersionProperties extends DefaultTask { - private FileCollection effectiveBoms; + private FileCollection resolvedBoms; @InputFiles @PathSensitive(PathSensitivity.RELATIVE) - public FileCollection getEffectiveBoms() { - return this.effectiveBoms; + public FileCollection getResolvedBoms() { + return this.resolvedBoms; } - public void setEffectiveBoms(FileCollection effectiveBoms) { - this.effectiveBoms = effectiveBoms; + public void setResolvedBoms(FileCollection resolvedBoms) { + this.resolvedBoms = resolvedBoms; } @OutputFile @@ -483,8 +479,8 @@ public class MavenPluginPlugin implements Plugin { @TaskAction public void extractVersionProperties() { - EffectiveBom effectiveBom = new EffectiveBom(this.effectiveBoms.getSingleFile()); - Properties versions = extractVersionProperties(effectiveBom); + ResolvedBom resolvedBom = ResolvedBom.readFrom(this.resolvedBoms.getSingleFile()); + Properties versions = extractVersionProperties(resolvedBom); writeProperties(versions); } @@ -499,68 +495,20 @@ public class MavenPluginPlugin implements Plugin { } } - private Properties extractVersionProperties(EffectiveBom effectiveBom) { + private Properties extractVersionProperties(ResolvedBom resolvedBom) { Properties versions = CollectionFactory.createSortedProperties(true); - versions.setProperty("project.version", effectiveBom.version()); - effectiveBom.property("log4j2.version", versions::setProperty); - effectiveBom.property("maven-jar-plugin.version", versions::setProperty); - effectiveBom.property("maven-war-plugin.version", versions::setProperty); - effectiveBom.property("build-helper-maven-plugin.version", versions::setProperty); - effectiveBom.property("spring-framework.version", versions::setProperty); - effectiveBom.property("jakarta-servlet.version", versions::setProperty); - effectiveBom.property("kotlin.version", versions::setProperty); - effectiveBom.property("assertj.version", versions::setProperty); - effectiveBom.property("junit-jupiter.version", versions::setProperty); + versions.setProperty("project.version", resolvedBom.id().version()); + Set versionProperties = Set.of("log4j2.version", "maven-jar-plugin.version", + "maven-war-plugin.version", "build-helper-maven-plugin.version", "spring-framework.version", + "jakarta-servlet.version", "kotlin.version", "assertj.version", "junit-jupiter.version"); + for (ResolvedLibrary library : resolvedBom.libraries()) { + if (library.versionProperty() != null && versionProperties.contains(library.versionProperty())) { + versions.setProperty(library.versionProperty(), library.version()); + } + } return versions; } } - private static final class EffectiveBom { - - private final Document document; - - private final XPath xpath; - - private EffectiveBom(File bomFile) { - this.document = loadDocument(bomFile); - this.xpath = XPathFactory.newInstance().newXPath(); - } - - private Document loadDocument(File bomFile) { - try { - try (InputStream inputStream = new FileInputStream(bomFile)) { - DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = builderFactory.newDocumentBuilder(); - return builder.parse(inputStream); - } - } - catch (ParserConfigurationException | SAXException | IOException ex) { - throw new IllegalStateException(ex); - } - } - - private String version() { - return get("version"); - } - - private void property(String name, BiConsumer handler) { - handler.accept(name, get("properties/" + name)); - } - - private String get(String expression) { - try { - Node node = (Node) this.xpath.compile("/project/" + expression) - .evaluate(this.document, XPathConstants.NODE); - String text = (node != null) ? node.getTextContent() : null; - Assert.hasLength(text, () -> "No result for expression " + expression); - return text; - } - catch (XPathExpressionException ex) { - throw new IllegalStateException(ex); - } - } - - } - } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle index 83ba59974aa..21ede5e5b91 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle @@ -82,7 +82,7 @@ dependencies { mavenRepository(project(path: ":spring-boot-project:spring-boot-docker-compose", configuration: "mavenRepository")) mavenRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-parent", configuration: "mavenRepository")) - versionProperties(project(path: ":spring-boot-project:spring-boot-dependencies", configuration: "effectiveBom")) + versionProperties(project(path: ":spring-boot-project:spring-boot-dependencies", configuration: "resolvedBom")) } ext {