From ad1cb4235fbb0786cf6766ef78de02ec3dc397e7 Mon Sep 17 00:00:00 2001 From: Hyunwoo Jung Date: Mon, 7 Sep 2026 13:09:35 +0900 Subject: [PATCH] Avoid invoking Task.project at execution time in ShadowSource ShadowSource invoked Task.project at execution time to resolve source artifacts and perform file operations, which Gradle 10 will reject. Inject FileSystemOperations and ArchiveOperations instead of accessing Project, and replace the Configuration input with an ArtifactView-backed ConfigurableFileCollection to support the configuration cache. Also update the javapoet and objenesis dependencies in spring-core to use 'transitive = false' instead of '@jar' so that module metadata is preserved during sources variant reselection. Signed-off-by: Hyunwoo Jung --- .../build/shadow/ShadowSource.java | 113 ++++++++---------- spring-core/spring-core.gradle | 4 +- 2 files changed, 51 insertions(+), 66 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/build/shadow/ShadowSource.java b/buildSrc/src/main/java/org/springframework/build/shadow/ShadowSource.java index 6e3528f063bb..b1e484cd0a0d 100644 --- a/buildSrc/src/main/java/org/springframework/build/shadow/ShadowSource.java +++ b/buildSrc/src/main/java/org/springframework/build/shadow/ShadowSource.java @@ -18,30 +18,31 @@ import java.io.File; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Set; + +import javax.inject.Inject; import org.gradle.api.DefaultTask; import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.component.ModuleComponentSelector; -import org.gradle.api.artifacts.query.ArtifactResolutionQuery; -import org.gradle.api.artifacts.result.ArtifactResolutionResult; -import org.gradle.api.artifacts.result.ComponentArtifactsResult; -import org.gradle.api.artifacts.result.DependencyResult; -import org.gradle.api.artifacts.result.ResolutionResult; -import org.gradle.api.artifacts.result.ResolvedArtifactResult; +import org.gradle.api.attributes.Bundling; +import org.gradle.api.attributes.Category; +import org.gradle.api.attributes.DocsType; +import org.gradle.api.attributes.Usage; +import org.gradle.api.file.ArchiveOperations; +import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.FileCollection; import org.gradle.api.file.FileCopyDetails; +import org.gradle.api.file.FileSystemOperations; import org.gradle.api.file.FileTree; -import org.gradle.api.tasks.Classpath; +import org.gradle.api.model.ObjectFactory; import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.Nested; -import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.OutputDirectory; +import org.gradle.api.tasks.PathSensitive; +import org.gradle.api.tasks.PathSensitivity; import org.gradle.api.tasks.TaskAction; -import org.gradle.jvm.JvmLibrary; -import org.gradle.language.base.artifact.SourcesArtifact; /** * Gradle task to add source from shadowed jars into our own source jars. @@ -49,23 +50,44 @@ * @author Phillip Webb * @author Andy Wilkinson */ -public class ShadowSource extends DefaultTask { +public abstract class ShadowSource extends DefaultTask { - private final DirectoryProperty outputDirectory = getProject().getObjects().directoryProperty(); + private final List relocations = new ArrayList<>(); - private List configurations = new ArrayList<>(); - private final List relocations = new ArrayList<>(); + @InputFiles + @PathSensitive(PathSensitivity.NONE) + public abstract ConfigurableFileCollection getSourceJars(); + @OutputDirectory + public abstract DirectoryProperty getOutputDirectory(); - @Classpath - @Optional - public List getConfigurations() { - return this.configurations; - } + @Inject + protected abstract FileSystemOperations getFileSystemOperations(); + + @Inject + protected abstract ArchiveOperations getArchiveOperations(); + + @Inject + protected abstract ObjectFactory getObjectFactory(); public void setConfigurations(List configurations) { - this.configurations = configurations; + for (Configuration configuration : configurations) { + getSourceJars().from(resolveSourceArtifacts(configuration)); + } + } + + private FileCollection resolveSourceArtifacts(Configuration configuration) { + ObjectFactory objects = getObjectFactory(); + return configuration.getIncoming().artifactView(view -> { + view.withVariantReselection(); + view.attributes(attributes -> { + attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.class, Usage.JAVA_RUNTIME)); + attributes.attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.class, Category.DOCUMENTATION)); + attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.class, Bundling.EXTERNAL)); + attributes.attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named(DocsType.class, DocsType.SOURCES)); + }); + }).getFiles(); } @Nested @@ -77,52 +99,15 @@ public void relocate(String pattern, String destination) { this.relocations.add(new Relocation(pattern, destination)); } - @OutputDirectory - public DirectoryProperty getOutputDirectory() { - return this.outputDirectory; - } - @TaskAction void syncSourceJarFiles() { - sync(getSourceJarFiles()); - } - - private List getSourceJarFiles() { - List sourceJarFiles = new ArrayList<>(); - for (Configuration configuration : this.configurations) { - ResolutionResult resolutionResult = configuration.getIncoming().getResolutionResult(); - resolutionResult.getRootComponent().get().getDependencies().forEach(dependency -> { - Set artifactsResults = resolveSourceArtifacts(dependency); - for (ComponentArtifactsResult artifactResult : artifactsResults) { - artifactResult.getArtifacts(SourcesArtifact.class).forEach(sourceArtifact -> { - sourceJarFiles.add(((ResolvedArtifactResult) sourceArtifact).getFile()); - }); - } - }); - } - return Collections.unmodifiableList(sourceJarFiles); - } - - private Set resolveSourceArtifacts(DependencyResult dependency) { - ModuleComponentSelector componentSelector = (ModuleComponentSelector) dependency.getRequested(); - ArtifactResolutionQuery query = getProject().getDependencies().createArtifactResolutionQuery() - .forModule(componentSelector.getGroup(), componentSelector.getModule(), componentSelector.getVersion()); - return executeQuery(query).getResolvedComponents(); - } - - @SuppressWarnings("unchecked") - private ArtifactResolutionResult executeQuery(ArtifactResolutionQuery query) { - return query.withArtifacts(JvmLibrary.class, SourcesArtifact.class).execute(); - } - - private void sync(List sourceJarFiles) { - getProject().sync(spec -> { - spec.into(this.outputDirectory); + getFileSystemOperations().sync(spec -> { + spec.into(getOutputDirectory()); spec.eachFile(this::relocateFile); spec.filter(this::transformContent); spec.exclude("META-INF/**"); spec.setIncludeEmptyDirs(false); - sourceJarFiles.forEach(sourceJar -> spec.from(zipTree(sourceJar))); + getSourceJars().forEach(sourceJar -> spec.from(zipTree(sourceJar))); }); } @@ -142,7 +127,7 @@ private String transformContent(String content) { } private FileTree zipTree(File sourceJar) { - return getProject().zipTree(sourceJar); + return getArchiveOperations().zipTree(sourceJar); } diff --git a/spring-core/spring-core.gradle b/spring-core/spring-core.gradle index 4c0df4f03d56..1b74b3026a26 100644 --- a/spring-core/spring-core.gradle +++ b/spring-core/spring-core.gradle @@ -71,8 +71,8 @@ tasks.register('objenesisSourceJar', Jar) { } dependencies { - javapoet("com.palantir.javapoet:javapoet:${javapoetVersion}@jar") - objenesis("org.objenesis:objenesis:${objenesisVersion}@jar") + javapoet("com.palantir.javapoet:javapoet:${javapoetVersion}") { transitive = false } + objenesis("org.objenesis:objenesis:${objenesisVersion}") { transitive = false } api(files(javapoetRepackJar)) api(files(objenesisRepackJar)) api("commons-logging:commons-logging")