Don't use raw cached filenames in AggregatedJavadoc

Update `AggregatedJavadoc` so that jar names are constructed from
resolved artifact IDs rather than using the raw cache filename. Without
this change, javadoc generation fails when consuming SNAPSHOT
dependencies.

See gh-51456
This commit is contained in:
Phillip Webb
2026-09-17 18:29:12 -07:00
parent f7c699ebdc
commit dc1daa53bf
3 changed files with 41 additions and 10 deletions
@@ -220,8 +220,8 @@ class BomResolver {
private void addOfflineJavadocLink(Map<URI, List<String>> offlineJavadocLinks, Link link, Object version,
Stream<String> moduleNames) {
URI uri = URI.create(link.url(new LinkedVersion(version)));
offlineJavadocLinks.computeIfAbsent(uri, (key) -> new ArrayList<>())
.addAll(moduleNames.map((name) -> "%s-%s-javadoc.jar".formatted(name, version)).toList());
List<String> jars = moduleNames.map((name) -> "%s-%s-javadoc.jar".formatted(name, version)).toList();
offlineJavadocLinks.computeIfAbsent(uri, (key) -> new ArrayList<>()).addAll(jars);
}
private static final class Node {
@@ -31,10 +31,16 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.gradle.api.UncheckedIOException;
import org.gradle.api.artifacts.component.ComponentIdentifier;
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import org.gradle.api.artifacts.result.ResolvedArtifactResult;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.FileCollection;
import org.gradle.api.logging.LogLevel;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.javadoc.Javadoc;
import org.gradle.external.javadoc.StandardJavadocDocletOptions;
@@ -72,13 +78,36 @@ public abstract class AggregatedJavadoc extends Javadoc {
IGNORED_PACKAGES = Collections.unmodifiableList(ignoredPackages);
}
public void javadocJars(Provider<Set<ResolvedArtifactResult>> artifacts) {
getJavadocJarFiles().set(artifacts.map(this::asJavadocJarFiles));
getJavadocJarNames().set(artifacts.map(this::asJavadocJarNames));
}
private List<File> asJavadocJarFiles(Set<ResolvedArtifactResult> artifacts) {
return artifacts.stream().map(ResolvedArtifactResult::getFile).toList();
}
private List<String> asJavadocJarNames(Set<ResolvedArtifactResult> artifacts) {
return artifacts.stream().map(this::asJavadocJarName).toList();
}
private String asJavadocJarName(ResolvedArtifactResult artifact) {
ComponentIdentifier identifier = artifact.getId().getComponentIdentifier();
if (identifier instanceof ModuleComponentIdentifier moduleIdentifier) {
return "%s-%s-javadoc.jar".formatted(moduleIdentifier.getModule(), moduleIdentifier.getVersion());
}
return identifier.getDisplayName();
}
@Classpath
@InputFiles
public abstract ConfigurableFileCollection getResolvedBom();
@Classpath
@InputFiles
public abstract ConfigurableFileCollection getJavadocJars();
abstract ListProperty<File> getJavadocJarFiles();
@Input
abstract ListProperty<String> getJavadocJarNames();
@Override
protected void generate() {
@@ -147,11 +176,13 @@ public abstract class AggregatedJavadoc extends Javadoc {
}
private void extractJavdocListFiles(File javadocListsDir) {
getJavadocJars().forEach((javadocJar) -> {
FileCollection source = getProject().zipTree(javadocJar).filter(this::isJavadocListFile);
File destination = new File(javadocListsDir, javadocJar.getName());
List<File> files = getJavadocJarFiles().get();
List<String> names = getJavadocJarNames().get();
for (int i = 0; i < files.size(); i++) {
FileCollection source = getProject().zipTree(files.get(i)).filter(this::isJavadocListFile);
File destination = new File(javadocListsDir, names.get(i));
getProject().copy((copy) -> copy.from(source).into(destination));
});
}
}
private boolean isJavadocListFile(File file) {
+2 -2
View File
@@ -165,7 +165,7 @@ configurations {
def aggregatedJavadoc = tasks.register('aggregatedJavadoc', AggregatedJavadoc) {
resolvedBom.from(configurations.resolvedBom)
javadocJars.from(configurations.runtimeClasspath.incoming.artifactView {
javadocJars(configurations.runtimeClasspath.incoming.artifactView {
withVariantReselection()
attributes {
lenient = true
@@ -174,7 +174,7 @@ def aggregatedJavadoc = tasks.register('aggregatedJavadoc', AggregatedJavadoc) {
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling, Bundling.EXTERNAL));
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named(DocsType, "implicitjavadoc"));
}
}.files)
}.artifacts.resolvedArtifacts)
destinationDir = project.file(project.layout.buildDirectory.dir("docs/javadoc"))
source = configurations.javadocSource
classpath = configurations.runtimeClasspath