IntelliJ IDEA 中使用 Gradle 之 Download gradle-x.y.z-src.zip

环境

gradle-9.3.0

现象

当 WRAPPER 为 gradle-bin,总会自动下载 gradle-x.y.z-src.zip。

由于网络问题,下载缓慢,但 URI 无处修改。

下载到 .gradle/.tmp/gradle_downloadXXXbin,不能断点续传,不能提前顶替。

原因

IDEA GradleProjectResolver 引入 KotlinDslScriptModelResolver,KotlinDslScriptsModel 属性 sourcePath,等于 gradleSource() + classpathSources + accessorsClassPath.

gradleSource 其中用到的 ExternalResourceRepository 为 "Gradle distributions" (lvy pattern 'https://services.gradle.org/distributions/[module]-[revision](-[classifier])(.[ext])').

Workaround

1. 预制 gradle src: gradle-all.zip(荐)

判断是否下载的标的是 gradleInstallation/src, 此项 gradle-all.zip 中存在。

操作上,修改 gradle-wrapper.properties 中 distributionUrl 为 gradle-all.

2. 预制 file cache: caches/modules-2

由于 services.gradle.org/distributions 不存在 gradle-9.3.0-src.zip.sha1,且 HTTP HEAD gradle-9.3.0-src.zip 也无法获取到 sha1 信息,仅预制 caches/modules-2/files-2.1/gradle/gradle/9.3.0/<sha1sum>/gradle-9.3.0-src.zip,是达不到预制效果的。

预制 caches/modules-2/metadata-2.107/resource-at-url.bin 也是必须的。

foo/build.gradle.kts
import org.gradle.api.internal.artifacts.DefaultModuleIdentifier
import org.gradle.api.internal.artifacts.ivyservice.modulecache.FileStoreAndIndexProvider
import org.gradle.internal.component.external.model.DefaultModuleComponentIdentifier
import org.gradle.internal.component.external.model.ModuleComponentArtifactMetadata
import org.gradle.internal.component.external.model.UrlBackedArtifactMetadata
import org.gradle.internal.hash.HashCode
import org.gradle.internal.resource.ExternalResourceName
import org.gradle.internal.resource.cached.CachedExternalResource
import org.gradle.internal.resource.local.LocallyAvailableResourceFinder
import org.gradle.internal.resource.metadata.DefaultExternalResourceMetaData
import org.gradle.internal.resource.metadata.ExternalResourceMetaData
import org.gradle.internal.resource.transport.http.DefaultHttpSettings
import org.gradle.internal.resource.transport.http.DefaultSslContextFactory
import org.gradle.internal.resource.transport.http.HttpClientHelper
import org.gradle.internal.resource.transport.http.HttpResourceAccessor
import org.gradle.internal.verifier.HttpRedirectVerifier
import org.gradle.kotlin.dsl.support.serviceOf
import java.net.URI
import java.time.Instant
import java.util.*

abstract class CacheInspectorTask : DefaultTask() {
    companion object {
        private const val GRADLE_VERSION = "9.3.0"
        private const val SOURCE_DIST_URL = "https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-src.zip"
        private const val EXPECTED_SHA1 = "ddc52fbf46cb42d6a147f012d715357ffd33e624"
    }

    @TaskAction
    fun inspectCache() {
        val url = SOURCE_DIST_URL
        val uri = URI(url)

        logger.lifecycle("Handling cache for resource: $url")

        val cacheIndex = project.serviceOf<FileStoreAndIndexProvider>().externalResourceIndex

        cacheIndex.lookup(url)?.let { cachedEntry ->
            // cacheIndex.clear(url)
            logCachedEntry(url, cachedEntry)
            return
        }

        val localResourceFile = findLocalResourceBySha1() ?: return

        fetchAndStoreRemoteMetadata(uri, localResourceFile)
    }

    private fun findLocalResourceBySha1(): java.io.File? {
        val artifact = UrlBackedArtifactMetadata(
            DefaultModuleComponentIdentifier(
                DefaultModuleIdentifier.newId("gradle", "gradle"),
                GRADLE_VERSION
            ),   // componentIdentifier
            "",  // fileName
            ""   // relativeUrl
        )

        val localFinder = project.serviceOf<LocallyAvailableResourceFinder<ModuleComponentArtifactMetadata>>()
        val candidates = localFinder.findCandidates(artifact)

        if (candidates.isNone) {
            logger.lifecycle("No local resource found for artifact ${artifact.id}")
            return null
        }

        logger.lifecycle("Found local resource: ${artifact.id} (file-2.1 cache)")

        val local = candidates.findByHashValue(HashCode.fromString(EXPECTED_SHA1))
        if (local == null) {
            logger.lifecycle("Local resource found but SHA-1 checksum does NOT match expected value.")
            return null
        }

        return local.file
    }

    private fun fetchAndStoreRemoteMetadata(uri: URI, localFile: java.io.File) {
        val httpClientHelper = createHttpClientHelper()
        val httpResourceAccessor = HttpResourceAccessor(httpClientHelper)

        logger.lifecycle("Fetching remote metadata from $uri")
        val remoteMetadata = runCatching {
            httpResourceAccessor.getMetaData(ExternalResourceName(uri), false)
        }.getOrElse { e ->
            logger.lifecycle("Failed to fetch remote metadata: ${e.message}")
            return
        }

        if (remoteMetadata == null) {
            logger.lifecycle("No remote metadata found at $uri")
            return
        }

        logRemoteMetadata(remoteMetadata)

        val newMetadata = DefaultExternalResourceMetaData(
            uri,
            remoteMetadata.lastModified?.time ?: Instant.now().epochSecond,
            remoteMetadata.contentLength,
            remoteMetadata.contentType,
            remoteMetadata.etag,
            remoteMetadata.sha1
        )

        logger.lifecycle("Storing new cache entry for $uri")
        val cacheIndex = project.serviceOf<FileStoreAndIndexProvider>().externalResourceIndex
        cacheIndex.store(SOURCE_DIST_URL, localFile, newMetadata)
        logger.lifecycle("Cache updated successfully")
    }

    private fun createHttpClientHelper(): HttpClientHelper {
        val settings = DefaultHttpSettings.builder()
            .maxRedirects(2) // <-- for 307, 302
            .withAuthenticationSettings(Collections.emptyList())
            .withSslContextFactory(DefaultSslContextFactory())
            .withRedirectVerifier { HttpRedirectVerifier {} }
            .build()

        val factory = project.serviceOf<HttpClientHelper.Factory>()
        return factory.create(settings)
    }

    private fun logCachedEntry(url: String, entry: CachedExternalResource) {
        logger.lifecycle("Cache entry found for '$url':")
        logger.lifecycle("  cachedFile: ${entry.cachedFile}")
        logger.lifecycle("  cachedAt: ${entry.cachedAt}")
        logger.lifecycle("  metadata:")
        val meta = entry.externalResourceMetaData
        if (meta == null) {
            logger.lifecycle("    (no metadata available)")
            return
        }
        with(meta) {
            logger.lifecycle("    location: $location")
            logger.lifecycle("    lastModified: $lastModified (${lastModified?.time})")
            logger.lifecycle("    contentType: $contentType")
            logger.lifecycle("    contentLength: $contentLength")
            logger.lifecycle("    etag: $etag")
            logger.lifecycle("    sha1: $sha1")
        }
    }

    private fun logRemoteMetadata(metadata: ExternalResourceMetaData) {
        logger.lifecycle("Remote metadata fetched:")
        logger.lifecycle("  location: ${metadata.location}")
        logger.lifecycle("  lastModified: ${metadata.lastModified} (${metadata.lastModified?.time})")
        logger.lifecycle("  contentType: ${metadata.contentType}")
        logger.lifecycle("  contentLength: ${metadata.contentLength}")
        logger.lifecycle("  etag: ${metadata.etag}")
        logger.lifecycle("  sha1: ${metadata.sha1}")
    }
}

tasks.register<CacheInspectorTask>("cacheInspector") {}

3. 放弃 gradle src: 空文件夹(慎)

4. 反射修改 detachedConfiguration1 中 repositories (难,脆弱)

DependencyResolutionListener (beforeResolve, afterResolve)

Internal

KotlinDslScriptsModel 

idea-plugin/kotlin/gradle/gradle-tooling-impl/KotlinDslScriptModelProvider
package org.jetbrains.kotlin.idea.gradleTooling

class KotlinDslScriptModelProvider : ProjectImportModelProvider {

    private val kotlinDslScriptModelClass: Class<*> = KotlinDslScriptsModel::class.java

    override fun getPhase(): GradleModelFetchPhase = GradleModelFetchPhase.SCRIPT_MODEL_PHASE

    override fun populateModels(
        controller: BuildController,
        buildModels: Collection<GradleBuild>,
        modelConsumer: GradleModelConsumer
    ) {
        buildModels.flatMap { it.projects }.forEach {
            if (it.parent == null) {
                try {
                    val model = controller.findModel(it, kotlinDslScriptModelClass)
                    if (model != null) {
                        modelConsumer.consumeProjectModel(it, model, kotlinDslScriptModelClass)
                    }
                } catch (e: Throwable) {
                    modelConsumer.consumeProjectModel(
                        it,
                        BrokenKotlinDslScriptsModel(e), kotlinDslScriptModelClass
                    )
                }
            }
        }
    }
}
gradle/platforms/core-configuration/kotlin-dsl-tooling-builders/KotlinDslScriptsModelBuilder
package org.gradle.kotlin.dsl.tooling.builders

internal
abstract class AbstractKotlinDslScriptsModelBuilder : ToolingModelBuilder {

    companion object {
        private
        const val MODEL_NAME = "org.gradle.tooling.model.kotlin.dsl.KotlinDslScriptsModel"
    }

    override fun canBuild(modelName: String): Boolean =
        modelName == MODEL_NAME

    override fun buildAll(modelName: String, project: Project): KotlinDslScriptsModel {
        requireRootProject(project)
        val timer = Time.startTimer()
        val parameter = prepareParameter(project)
        try {
            return project.leaseRegistry.allowUncontrolledAccessToAnyProject {
                buildFor(parameter, project).also {
                    log("$parameter => $it - took ${timer.elapsed}")
                }
            }
        } catch (ex: Exception) {
            log("$parameter => $ex - took ${timer.elapsed}")
            throw ex
        }
    }

    abstract fun prepareParameter(rootProject: Project): KotlinDslScriptsParameter

    abstract fun buildFor(parameter: KotlinDslScriptsParameter, rootProject: Project): KotlinDslScriptsModel

    private
    val Project.leaseRegistry: ProjectLeaseRegistry
        get() = serviceOf()

    private
    fun requireRootProject(project: Project) =
        require(project == project.rootProject) {
            "$MODEL_NAME can only be requested on the root project, got $project"
        }
}


internal
object KotlinDslScriptsModelBuilder : AbstractKotlinDslScriptsModelBuilder() {

    override fun prepareParameter(rootProject: Project) = rootProject.parameterFromRequest()

    override fun buildFor(parameter: KotlinDslScriptsParameter, rootProject: Project): KotlinDslScriptsModel {
        val scriptModels = parameter.scriptFiles.associateWith { scriptFile ->
            buildScriptModel(rootProject, scriptFile, parameter)
        }
        return StandardKotlinDslScriptsModel.from(scriptModels)
    }

    private
    fun buildScriptModel(
        rootProject: Project,
        scriptFile: File,
        parameter: KotlinDslScriptsParameter
    ): StandardKotlinDslScriptModel {

        val scriptModelParameter = KotlinBuildScriptModelParameter(scriptFile, parameter.correlationId)
        val scriptModel = KotlinBuildScriptModelBuilder.kotlinBuildScriptModelFor(rootProject, scriptModelParameter)
        return StandardKotlinDslScriptModel(
            scriptModel.classPath,
            scriptModel.sourcePath,
            scriptModel.implicitImports,
            mapEditorReports(scriptModel.editorReports),
            scriptModel.exceptions
        )
    }
}
gradle/platforms/core-configuration/kotlin-dsl-tooling-builders/KotlinScriptTargetModelBuilder
package org.gradle.kotlin.dsl.tooling.builders

private
data class KotlinScriptTargetModelBuilder(
    val scriptFile: File?,
    val project: Project,
    val scriptClassPath: ClassPath,
    val accessorsClassPath: (ClassPath) -> AccessorsClassPath = { AccessorsClassPath.empty },
    val sourceLookupScriptHandlers: List<ScriptHandler> = emptyList(),
    val enclosingScriptProjectDir: File? = null,
    val additionalImports: () -> List<String> = { emptyList() }
) {

    fun buildModel(): KotlinBuildScriptModel {
        val classpathSources = sourcePathFor(sourceLookupScriptHandlers)
        val classPathModeExceptionCollector = project.serviceOf<ClassPathModeExceptionCollector>()
        val accessorsClassPath =
            classPathModeExceptionCollector.runCatching {
                accessorsClassPath(scriptClassPath)
            } ?: AccessorsClassPath.empty

        val additionalImports =
            classPathModeExceptionCollector.runCatching {
                additionalImports()
            } ?: emptyList()

        val exceptions = classPathModeExceptionCollector.exceptions
        return StandardKotlinBuildScriptModel(
            (scriptClassPath + accessorsClassPath.bin).asFiles,
            (gradleSource() + classpathSources + accessorsClassPath.src).asFiles,
            project.scriptImplicitImports + additionalImports,
            buildEditorReportsFor(exceptions),
            getExceptionsForFile(exceptions, this.scriptFile),
            enclosingScriptProjectDir
        )
    }
    
    private
    fun gradleSource() =
        SourcePathProvider.sourcePathFor(
            scriptClassPath,
            scriptFile,
            project.rootDir,
            project.gradle.gradleHomeDir,
            SourceDistributionResolver(project)
        )

    ...
}

gradleSource()

gradle/platforms/core-configuration/kotlin-dsl/SourcePathProvider
package org.gradle.kotlin.dsl.resolver

const val BUILD_SRC_SOURCE_ROOTS_FILE_PATH = "build/source-roots/buildSrc/source-roots.txt"


object SourcePathProvider {

    fun sourcePathFor(
        classPath: ClassPath,
        scriptFile: File?,
        projectDir: File,
        gradleHomeDir: File?,
        sourceDistributionResolver: SourceDistributionProvider
    ): ClassPath {
        val gradleKotlinDslJar = classPath.filter(::isGradleKotlinDslJar)
        val gradleSourceRoots = gradleHomeDir?.let { sourceRootsOf(it, sourceDistributionResolver) } ?: emptyList()

        // If the script file is known, determine its type
        val scriptType = scriptFile?.let {
            KotlinScriptTypeMatch.forFile(it)?.scriptType
        }

        // We also add the "buildSrc" sources onto the source path.
        val projectBuildSrcRoots = when (scriptType) {
            KotlinScriptType.INIT, KotlinScriptType.SETTINGS -> emptyList()
            else -> buildSrcRootsOf(projectDir)
        }

        return gradleKotlinDslJar + projectBuildSrcRoots + gradleSourceRoots
    }

    /**
     * Returns source directories from buildSrc if any.
     */
    fun buildSrcRootsOf(projectRoot: File): Collection<File> =
        projectRoot.resolve("buildSrc/$BUILD_SRC_SOURCE_ROOTS_FILE_PATH")
            .takeIf { it.isFile }
            ?.readLines()
            ?.map { projectRoot.resolve("buildSrc/$it") }
            ?: buildSrcRootsFallbackFor(projectRoot)

    private
    fun buildSrcRootsFallbackFor(projectRoot: File) =
        subDirsOf(File(projectRoot, "buildSrc/src/main"))

    fun sourceRootsOf(gradleInstallation: File, sourceDistributionResolver: SourceDistributionProvider): Collection<File> =
        gradleInstallationSources(gradleInstallation) ?: downloadedSources(sourceDistributionResolver)

    private
    fun gradleInstallationSources(gradleInstallation: File) =
        File(gradleInstallation, "src").takeIf { it.exists() }?.let { subDirsOf(it) }

    private
    fun downloadedSources(sourceDistributionResolver: SourceDistributionProvider) =
        sourceDistributionResolver.sourceDirs()
}


internal
fun subDirsOf(dir: File): Collection<File> =
    if (dir.isDirectory) dir.listFilesOrdered { it.isDirectory }
    else emptyList()

由 sourceRootsOf 可知,如果在 gradleInstallation 目录下没有发现 src 目录,就会开启下载。

gradle/platforms/core-configuration/kotlin-dsl/SourceDistributionResolver
package org.gradle.kotlin.dsl.resolver

interface SourceDistributionProvider {
    fun sourceDirs(): Collection<File>
}


class SourceDistributionResolver(private val project: Project) : SourceDistributionProvider {

    companion object {
        val artifactType: Attribute<String> = Attribute.of("artifactType", String::class.java)
        const val ZIP_TYPE = "zip"
        const val SOURCE_DIRECTORY = "src-directory"
    }

    override fun sourceDirs(): Collection<File> =
        try {
            sourceDirs
        } catch (ex: Exception) {
            project.logger.warn("Unexpected exception while resolving Gradle distribution sources: ${ex.message}", ex)
            emptyList()
        }

    private
    val sourceDirs by lazy {
        createSourceRepository()
        registerTransforms()
        transientConfigurationForSourcesDownload().files
    }

    private
    fun registerTransforms() {
        registerTransform<FindGradleSources> {
            from.attribute(artifactType, ZIP_TYPE)
            to.attribute(artifactType, SOURCE_DIRECTORY)
        }
    }

    private
    fun transientConfigurationForSourcesDownload() =
        detachedConfigurationFor(gradleSourceDependency()).apply {
            attributes.attribute(artifactType, SOURCE_DIRECTORY)
        }

    private
    fun detachedConfigurationFor(dependency: Dependency) =
        configurations.detachedConfiguration(dependency)

    private
    fun gradleSourceDependency() = dependencies.create("gradle:gradle:${dependencyVersion(gradleVersion)}") {
        artifact {
            classifier = "src"
            type = "zip"
        }
    }

    private
    fun createSourceRepository() = ivy {
        val repoName = repositoryNameFor(gradleVersion)
        name = "Gradle $repoName"
        setUrl("https://services.gradle.org/$repoName")
        metadataSources {
            artifact()
        }
        patternLayout {
            if (isSnapshot(gradleVersion)) {
                ivy("/dummy") // avoids a lookup that interferes with version listing
            }
            artifact("[module]-[revision](-[classifier])(.[ext])")
        }
    }

    private
    fun repositoryNameFor(gradleVersion: String) =
        if (isSnapshot(gradleVersion)) "distributions-snapshots" else "distributions"

    private
    fun dependencyVersion(gradleVersion: String) =
        if (isSnapshot(gradleVersion)) toVersionRange(gradleVersion) else gradleVersion

    private
    fun isSnapshot(gradleVersion: String) = gradleVersion.contains('+')

    private
    fun toVersionRange(gradleVersion: String) =
        "(${minimumGradleVersion()}, $gradleVersion]"

    private
    inline fun <reified T : TransformAction<TransformParameters.None>> registerTransform(configure: Action<TransformSpec<TransformParameters.None>>) =
        dependencies.registerTransform(T::class.java, configure)

    private
    fun ivy(configure: Action<IvyArtifactRepository>) =
        repositories.ivy(configure)

    private
    fun minimumGradleVersion(): String {
        val baseVersionString = GradleVersion.version(gradleVersion).baseVersion.version
        val (major, minor) = baseVersionString.split('.')
        return when (minor) {
            // TODO:kotlin-dsl consider commenting out this clause once the 1st 6.0 snapshot is out
            "0" -> {
                // When testing against a `major.0` snapshot we need to take into account
                // that source distributions matching the major version might not have
                // been published yet. In that case we adjust the constraint to include
                // source distributions beginning from the previous major version.
                "${previous(major)}.0"
            }

            else -> {
                // Otherwise include source distributions beginning from the previous minor version only.
                "$major.${previous(minor)}"
            }
        }
    }

    private
    fun previous(versionDigit: String) =
        Integer.parseInt(versionDigit) - 1

    private
    val resolver by lazy { projectInternal.newDetachedResolver() }

    private
    val projectInternal
        get() = project as ProjectInternal

    private
    val repositories
        get() = resolver.repositories

    private
    val configurations
        get() = resolver.configurations

    private
    val dependencies
        get() = resolver.dependencies

    private
    val gradleVersion
        get() = project.gradle.gradleVersion
}

由 sourceDirs 可知,大致对应配置如下,且全程在 projectInternal.newDetachedResolver() 影响范围内 (repositories, configurations, dependencies).

gradle-source.gradle.kts
repositories {
    ivy {
        name = "Gradle distributions"
        setUrl("https://services.gradle.org/distributions")
        metadataSources {
            artifact()
        }
        patternLayout {
            artifact("[module]-[revision](-[classifier])(.[ext])")
        }
    }
}

dependencies {
    detachedConfiguration("gradle:gradle:9.3.0") {
        artifact {
            classifier = "src"
            type = "zip"
        }
    }
    registerTransform(FindGradleSources::class.java) {
        from.attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, "zip")
        to.attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, "src-directory")
    }
}

downloadByCoords()

DefaultExternalResourceArtifactResolver
     private LocallyAvailableExternalResource downloadByCoords(List<ResourcePattern> patternList, final ModuleComponentArtifactMetadata artifact, ResourceAwareResolveResult result) {
        for (ResourcePattern resourcePattern : patternList) {
            if (isIncomplete(resourcePattern, artifact)) {
                continue;
            }
            ExternalResourceName location = resourcePattern.getLocation(artifact);
            result.attempted(location);
            LOGGER.debug("Loading {}", location);
            LocallyAvailableResourceCandidates localCandidates = locallyAvailableResourceFinder.findCandidates(artifact);
            try {
                LocallyAvailableExternalResource resource = resourceAccessor.getResource(location, null, getFileStore(artifact), localCandidates);
                if (resource != null) {
                    return resource;
                }
            } catch (Exception e) {
                throw ResourceExceptions.getFailed(location.getUri(), e);
            }
        }
        return null;
    }
DefaultCacheAwareExternalResourceAccessor
     public LocallyAvailableExternalResource getResource(final ExternalResourceName location, @Nullable String baseName, final ResourceFileStore fileStore, @Nullable final LocallyAvailableResourceCandidates additionalCandidates) {
        return producerGuard.guardByKey(location, () -> {
            LOGGER.debug("Constructing external resource: {}", location);
            CachedExternalResource cached = cachedExternalResourceIndex.lookup(location.toString());

            // If we have no caching options, just get the thing directly
            if (cached == null && (additionalCandidates == null || additionalCandidates.isNone())) {
                return copyToCache(location, fileStore, delegate.withProgressLogging().resource(location));
            }

            // We might be able to use a cached/locally available version
            if (cached != null && !externalResourceCachePolicy.mustRefreshExternalResource(getAgeMillis(timeProvider, cached))) {
                return fileResourceRepository.resource(cached.getCachedFile(), location.getUri(), cached.getExternalResourceMetaData());
            }

            // We have a cached version, but it might be out of date, so we tell the upstreams to revalidate too
            final boolean revalidate = true;

            // Get the metadata first to see if it's there
            final ExternalResourceMetaData remoteMetaData = delegate.resource(location, revalidate).getMetaData();
            if (remoteMetaData == null) {
                return null;
            }

            // Is the cached version still current?
            if (cached != null) {
                boolean isUnchanged = ExternalResourceMetaDataCompare.isDefinitelyUnchanged(
                    cached.getExternalResourceMetaData(),
                    () -> remoteMetaData
                );

                if (isUnchanged) {
                    LOGGER.info("Cached resource {} is up-to-date (lastModified: {}).", location, cached.getExternalLastModified());
                    // Update the cache entry in the index: this resets the age of the cached entry to zero
                    cachedExternalResourceIndex.store(location.toString(), cached.getCachedFile(), cached.getExternalResourceMetaData());
                    return fileResourceRepository.resource(cached.getCachedFile(), location.getUri(), cached.getExternalResourceMetaData());
                }
            }

            // Either no cached, or it's changed. See if we can find something local with the same checksum
            boolean hasLocalCandidates = additionalCandidates != null && !additionalCandidates.isNone();
            if (hasLocalCandidates) {
                // The "remote" may have already given us the checksum
                HashCode remoteChecksum = remoteMetaData.getSha1();

                if (remoteChecksum == null) {
                    remoteChecksum = getResourceSha1(location, revalidate);         // <-------
                }

                if (remoteChecksum != null) {
                    LocallyAvailableResource local = additionalCandidates.findByHashValue(remoteChecksum);
                    if (local != null) {
                        LOGGER.info("Found locally available resource with matching checksum: [{}, {}]", location, local.getFile());
                        // TODO - should iterate over each candidate until we successfully copy into the cache
                        LocallyAvailableExternalResource resource;
                        try {
                            resource = copyCandidateToCache(location, fileStore, remoteMetaData, remoteChecksum, local);
                        } catch (IOException e) {
                            throw UncheckedException.throwAsUncheckedException(e);
                        }
                        if (resource != null) {
                            return resource;
                        }
                    }
                }
            }

            // All local/cached options failed, get directly
            return copyToCache(location, fileStore, delegate.withProgressLogging().resource(location, revalidate));
        });
    }


    private HashCode getResourceSha1(ExternalResourceName location, boolean revalidate) {
        try {
            ExternalResourceName sha1Location = location.append(".sha1");
            ExternalResource resource = delegate.resource(sha1Location, revalidate);
            ExternalResourceReadResult<HashCode> result = resource.withContentIfPresent(inputStream -> {
                String sha = IOUtils.toString(inputStream, StandardCharsets.US_ASCII);
                // Servers may return SHA-1 with leading zeros stripped
                sha = StringUtils.leftPad(sha, Hashing.sha1().getHexDigits(), '0');
                return HashCode.fromString(sha);
            });
            return result == null ? null : result.getResult();
        } catch (Exception e) {
            LOGGER.debug(String.format("Failed to download SHA1 for resource '%s'.", location), e);
            return null;
        }
    }

当遇到 "gradle:gradle:9.3.0" 时,

  1. cachedExternalResourceIndex 是按 location 缓存的,若未从 services.gradle.org 下载过,无命中。
  2. additionalCandidates 可能有值。
    1. LocallyAvailableResourceFinderSearchableFileStoreAdapter
      1. fileStore.search(criterion).stream().map(LocallyAvailableResource::getFile).collect(Collectors.toList())
      2. 当预制 modules-2/file-2.1 时,能查询到。
    2. PatternBasedLocallyAvailableResourceFinder
  3. remoteMetaData 是 HTTP HEAD 方式去获取。可能发生 Read timed out,重试。
    1. 检查 etag, lastModified, contentLength 是否变动。
  4. LocalCandidates 检查,checksum sha1,无命中。
    1. 要查询 remoteMetaData (HEAD) header 中 sha1 值,不存在,无法命中。
    2. 要查询 gradle-xxx-src.zip.sha1,但 .sha1 文件在 services.gradle.org 不存在,无法命中。

DownloadAction

gradle/platforms/software/dependency-management/DefaultCacheAwareExternalResourceAccessor
package org.gradle.internal.resource.transfer;

public class DefaultCacheAwareExternalResourceAccessor implements CacheAwareExternalResourceAccessor {
    ...

    private LocallyAvailableExternalResource copyToCache(final ExternalResourceName source, final ResourceFileStore fileStore, final ExternalResource resource) {
        // Download to temporary location
        DownloadAction downloadAction = new DownloadAction(source, temporaryFileProvider, LOGGER);
        resource.withContentIfPresent(downloadAction);
        if (downloadAction.getMetaData() == null) {
            return null;
        }

        // Move into cache
        try {
            return moveIntoCache(source, downloadAction.getDestination(), fileStore, downloadAction.getMetaData());
        } finally {
            downloadAction.getDestination().delete();
        }
    }
}
gradle/platforms/software/dependency-management/DownloadAction
package org.gradle.internal.resource.transfer;

public class DownloadAction implements ExternalResource.ContentAndMetadataAction<Object> {
    ...
    @Override
    public Object execute(InputStream inputStream, ExternalResourceMetaData metaData) throws IOException {
        destination = temporaryFileProvider.createTemporaryFile("gradle_download", "bin");
        this.metaData = metaData;
        if (logger != null) {
            logger.info("Downloading {} to {}", source, destination);
        }
        if (destination.getParentFile() != null) {
            GFileUtils.mkdirs(destination.getParentFile());
        }
        try (FileOutputStream outputStream = new FileOutputStream(destination)) {
            IOUtils.copyLarge(inputStream, outputStream);
        }
        return null;
    }
    ...
}
gradle/platforms/software/resources/AccessorBackedExternalResource
 package org.gradle.internal.resource.transfer;

public class AccessorBackedExternalResource extends AbstractExternalResource {
    ...
        
    public <T> ExternalResourceReadResult<T> withContentIfPresent(ContentAndMetadataAction<? extends T> readAction) throws ResourceException {
        return accessor.withContent(name, revalidate, (inputStream, metadata) -> {
            try (CountingInputStream stream = new CountingInputStream(new BufferedInputStream(inputStream))) {
                T value = readAction.execute(stream, metadata);
                return ExternalResourceReadResult.of(stream.getCount(), value);
            }
        });
    }
}
gradle/platforms/software/dependency-management/ProgressLoggingExternalResourceAccessor
 package org.gradle.internal.resource.transfer;

public class ProgressLoggingExternalResourceAccessor extends AbstractProgressLoggingHandler implements ExternalResourceAccessor {
    ...
        
    public <T> T withContent(ExternalResourceName location, boolean revalidate, ExternalResource.ContentAndMetadataAction<T> action) throws ResourceException {
        return buildOperationRunner.call(new DownloadOperation<>(location, revalidate, action));
    }
}
gradle/platforms/software/dependency-management/ProgressLoggingExternalResourceAccessor$DownloadOperation
package org.gradle.internal.resource.transfer;

    private class DownloadOperation<T> implements CallableBuildOperation<T> {
        private final ExternalResourceName location;
        private final boolean revalidate;
        private final ExternalResource.ContentAndMetadataAction<T> action;

        public DownloadOperation(ExternalResourceName location, boolean revalidate, ExternalResource.ContentAndMetadataAction<T> action) {
            this.location = location;
            this.revalidate = revalidate;
            this.action = action;
        }

        @Override
        public T call(BuildOperationContext context) {
            ResourceOperation downloadOperation = createResourceOperation(context, ResourceOperation.Type.download);
            AtomicReference<ExternalResourceMetaData> metadata = new AtomicReference<>();
            try {
                return delegate.withContent(location, revalidate, (inputStream, metaData) -> {
                    downloadOperation.setContentLength(metaData.getContentLength());
                    metadata.set(metaData);
                    if(metaData.wasMissing()) {
                        context.failed(ResourceExceptions.getMissing(metaData.getLocation()));
                        return null;
                    }
                    ProgressLoggingInputStream stream = new ProgressLoggingInputStream(inputStream, downloadOperation::logProcessedBytes);
                    return action.execute(stream, metaData);
                });
            } finally {
                ExternalResourceMetaData externalResourceMetaData = metadata.get();
                context.setResult(new ReadOperationResult(
                    downloadOperation.getTotalProcessedBytes(),
                    externalResourceMetaData != null && externalResourceMetaData.wasMissing()
                ));
            }
        }

        @Override
        public BuildOperationDescriptor.Builder description() {
            return createBuildOperationDetails(location);
        }
    }
gradle/platforms/software/resources/DefaultExternalResourceConnector
package org.gradle.internal.resource.transfer;

public class DefaultExternalResourceConnector implements ExternalResourceConnector {
    ...
        
    public <T> T withContent(ExternalResourceName location, boolean revalidate, ExternalResource.ContentAndMetadataAction<T> action) throws ResourceException {
        STATS.resource(location.getUri());
        return accessor.withContent(location, revalidate, action);
    }
}
gradle/platforms/software/resources-http/HttpResourceAccessor
package org.gradle.internal.resource.transport.http;

public class HttpResourceAccessor extends AbstractExternalResourceAccessor implements ExternalResourceAccessor {

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpResourceAccessor.class);
    private final HttpClientHelper http;

    public HttpResourceAccessor(HttpClientHelper http) {
        this.http = http;
    }

    @Override
    @Nullable
    public HttpResponseResource openResource(final ExternalResourceName location, boolean revalidate) {
        String uri = location.getUri().toString();
        LOGGER.debug("Constructing external resource: {}", location);

        HttpClientResponse response = http.performGet(uri, revalidate);
        return wrapResponse(location.getUri(), response);
    }

    /**
     * Same as #getResource except that it always gives access to the response body,
     * irrespective of the returned HTTP status code. Never returns {@code null}.
     */
    public HttpResponseResource getRawResource(final URI uri, boolean revalidate) {
        String location = uri.toString();
        LOGGER.debug("Constructing external resource: {}", location);
        HttpClientResponse response = http.performRawGet(location, revalidate);
        return wrapResponse(uri, response);
    }

    @Override
    public ExternalResourceMetaData getMetaData(ExternalResourceName location, boolean revalidate) {
        String uri = location.getUri().toString();
        LOGGER.debug("Constructing external resource metadata: {}", location);
        HttpClientResponse response = http.performHead(uri, revalidate);

        if (response == null || response.wasMissing()) {
            return null;
        }

        HttpResponseResource resource = new HttpResponseResource("HEAD", location.getUri(), response);
        try {
            return resource.getMetaData();
        } finally {
            IoActions.closeQuietly(resource);
        }
    }

    private HttpResponseResource wrapResponse(URI uri, HttpClientResponse response) {
        return new HttpResponseResource("GET", uri, response);
    }

}
gradle/platforms/software/resources/AbstractExternalResourceAccessor
 public abstract class AbstractExternalResourceAccessor implements ExternalResourceAccessor {
    ...
        
    public <T> T withContent(ExternalResourceName location, boolean revalidate, ExternalResource.ContentAndMetadataAction<T> action) throws ResourceException {
        ExternalResourceReadResponse response = openResource(location, revalidate);
        if (response == null) {
            return null;
        }

        try (InputStream inputStream = response.openStream();
             ExternalResourceReadResponse responseCloser = response) {
            return action.execute(inputStream, responseCloser.getMetaData());
        } catch (IOException e) {
            throw ResourceExceptions.getFailed(location.getUri(), e);
        }
    }
}

stack trace

exception stack trace
Unexpected exception while resolving Gradle distribution sources: Could not resolve all files for configuration 'detachedConfiguration1'.
org.gradle.api.internal.artifacts.ivyservice.TypedResolveException: Could not resolve all files for configuration 'detachedConfiguration1'.
	at org.gradle.api.internal.artifacts.ResolveExceptionMapper.mapFailure(ResolveExceptionMapper.java:73)
	at org.gradle.api.internal.artifacts.ResolveExceptionMapper.mapFailures(ResolveExceptionMapper.java:65)
	at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$DefaultResolutionHost.consolidateFailures(DefaultConfiguration.java:1740)
	at org.gradle.api.internal.artifacts.configurations.ResolutionHost.rethrowFailuresAndReportProblems(ResolutionHost.java:75)
	at org.gradle.api.internal.artifacts.configurations.ResolutionBackedFileCollection.maybeThrowResolutionFailures(ResolutionBackedFileCollection.java:86)
	at org.gradle.api.internal.artifacts.configurations.ResolutionBackedFileCollection.visitContents(ResolutionBackedFileCollection.java:76)
	at org.gradle.api.internal.file.AbstractFileCollection.visitStructure(AbstractFileCollection.java:361)
	at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.visitContents(DefaultConfiguration.java:490)
	at org.gradle.api.internal.file.AbstractFileCollection.getFiles(AbstractFileCollection.java:124)
	at org.gradle.api.internal.artifacts.configurations.DefaultLegacyConfiguration_Decorated.getFiles(Unknown Source)
	at org.gradle.kotlin.dsl.resolver.SourceDistributionResolver.sourceDirs_delegate$lambda$0(SourceDistributionProvider.kt:58)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:86)
	at org.gradle.kotlin.dsl.resolver.SourceDistributionResolver.getSourceDirs(SourceDistributionProvider.kt:55)
	at org.gradle.kotlin.dsl.resolver.SourceDistributionResolver.sourceDirs(SourceDistributionProvider.kt:48)
	at org.gradle.kotlin.dsl.resolver.SourcePathProvider.downloadedSources(SourcePathProvider.kt:82)                                                               <--------------------
	at org.gradle.kotlin.dsl.resolver.SourcePathProvider.sourceRootsOf(SourcePathProvider.kt:74)
	at org.gradle.kotlin.dsl.resolver.SourcePathProvider.sourcePathFor(SourcePathProvider.kt:43)
	at org.gradle.kotlin.dsl.tooling.builders.KotlinScriptTargetModelBuilder.gradleSource(KotlinBuildScriptModelBuilder.kt:455)                                    <--------------------
	at org.gradle.kotlin.dsl.tooling.builders.KotlinScriptTargetModelBuilder.buildModel(KotlinBuildScriptModelBuilder.kt:436)
	at org.gradle.kotlin.dsl.tooling.builders.KotlinBuildScriptModelBuilder.kotlinBuildScriptModelFor$kotlin_dsl_tooling_builders(KotlinBuildScriptModelBuilder.kt:120)
	at org.gradle.kotlin.dsl.tooling.builders.KotlinDslScriptsModelBuilder.buildScriptModel(KotlinDslScriptsModelBuilder.kt:188)
	at org.gradle.kotlin.dsl.tooling.builders.KotlinDslScriptsModelBuilder.buildFor(KotlinDslScriptsModelBuilder.kt:175)
	at org.gradle.kotlin.dsl.tooling.builders.AbstractKotlinDslScriptsModelBuilder$buildAll$1.create(KotlinDslScriptsModelBuilder.kt:142)
	at org.gradle.kotlin.dsl.tooling.builders.AbstractKotlinDslScriptsModelBuilder$buildAll$1.create(KotlinDslScriptsModelBuilder.kt:141)
	at org.gradle.internal.resources.AbstractResourceLockRegistry.allowUncontrolledAccessToAnyResource(AbstractResourceLockRegistry.java:61)
	at org.gradle.internal.work.DefaultWorkerLeaseService.allowUncontrolledAccessToAnyProject(DefaultWorkerLeaseService.java:238)
	at org.gradle.kotlin.dsl.tooling.builders.AbstractKotlinDslScriptsModelBuilder.buildAll(KotlinDslScriptsModelBuilder.kt:141)
	at org.gradle.kotlin.dsl.tooling.builders.AbstractKotlinDslScriptsModelBuilder.buildAll(KotlinDslScriptsModelBuilder.kt:125)
	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$BuilderWithNoParameter.build(DefaultToolingModelBuilderRegistry.java:272)
	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$LockProjectStateBuilder.lambda$build$0(DefaultToolingModelBuilderRegistry.java:312)
	at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
	at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
	at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withReplacedLocks$3(DefaultWorkerLeaseService.java:365)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withoutLocks(DefaultWorkerLeaseService.java:337)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withReplacedLocks(DefaultWorkerLeaseService.java:364)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.runWithModelLock(DefaultProjectStateRegistry.java:471)
	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$LockProjectStateBuilder.build(DefaultToolingModelBuilderRegistry.java:312)
	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$BuildOperationWrappingBuilder$1.call(DefaultToolingModelBuilderRegistry.java:345)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$BuildOperationWrappingBuilder.build(DefaultToolingModelBuilderRegistry.java:342)
	at org.gradle.internal.build.DefaultBuildToolingModelController$AbstractToolingScope.getModel(DefaultBuildToolingModelController.java:88)
	at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator$DefaultBuildTreeModelController.getModelForScope(DefaultBuildTreeModelCreator.java:156)
	at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator$DefaultBuildTreeModelController.access$300(DefaultBuildTreeModelCreator.java:69)
	at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator$DefaultBuildTreeModelController$1.call(DefaultBuildTreeModelCreator.java:85)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator$DefaultBuildTreeModelController.getModel(DefaultBuildTreeModelCreator.java:80)
	at org.gradle.tooling.internal.provider.runner.DefaultBuildController.doGetModel(DefaultBuildController.java:126)
	at org.gradle.tooling.internal.provider.runner.DefaultBuildController.getModel(DefaultBuildController.java:113)
	at org.gradle.tooling.internal.consumer.connection.ParameterAwareBuildControllerAdapter.getModel(ParameterAwareBuildControllerAdapter.java:40)
	at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.getModel(UnparameterizedBuildController.java:119)
	at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.getModel(NestedActionAwareBuildControllerAdapter.java:32)
	at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.findModel(UnparameterizedBuildController.java:104)
	at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.findModel(NestedActionAwareBuildControllerAdapter.java:32)
	at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.findModel(UnparameterizedBuildController.java:88)
	at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.findModel(NestedActionAwareBuildControllerAdapter.java:32)
	at org.jetbrains.plugins.gradle.model.DefaultBuildController.findModel(DefaultBuildController.java:91)
	at org.jetbrains.kotlin.idea.gradleTooling.KotlinDslScriptModelProvider.populateModels(KotlinDslScriptModelProvider.kt:26)                                    <--------------------
	at com.intellij.gradle.toolingExtension.impl.modelAction.GradleModelFetchAction.lambda$populateModels$12(GradleModelFetchAction.java:250)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.lambda$runWithSpan$2(GradleOpenTelemetry.java:38)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.callWithSpan(GradleOpenTelemetry.java:56)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.lambda$callWithSpan$1(GradleOpenTelemetry.java:32)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.withOpenTelemetry(GradleOpenTelemetry.java:81)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.callWithSpan(GradleOpenTelemetry.java:31)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.runWithSpan(GradleOpenTelemetry.java:37)
	at com.intellij.gradle.toolingExtension.impl.modelAction.GradleModelFetchAction.populateModels(GradleModelFetchAction.java:249)
	at com.intellij.gradle.toolingExtension.impl.modelAction.GradleModelFetchAction.lambda$executeAction$10(GradleModelFetchAction.java:232)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.lambda$runWithSpan$2(GradleOpenTelemetry.java:38)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.callWithSpan(GradleOpenTelemetry.java:56)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.lambda$callWithSpan$1(GradleOpenTelemetry.java:32)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.withOpenTelemetry(GradleOpenTelemetry.java:81)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.callWithSpan(GradleOpenTelemetry.java:31)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.runWithSpan(GradleOpenTelemetry.java:37)
	at com.intellij.gradle.toolingExtension.impl.modelAction.GradleModelFetchAction.lambda$executeAction$11(GradleModelFetchAction.java:230)
	at java.base@21.0.10/java.util.ArrayList.forEach(ArrayList.java:1596)
	at com.intellij.gradle.toolingExtension.impl.modelAction.GradleModelFetchAction.executeAction(GradleModelFetchAction.java:229)                                <--------------------
	at com.intellij.gradle.toolingExtension.impl.modelAction.GradleModelFetchAction.lambda$doExecute$4(GradleModelFetchAction.java:131)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.lambda$runWithSpan$2(GradleOpenTelemetry.java:38)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.callWithSpan(GradleOpenTelemetry.java:56)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.lambda$callWithSpan$1(GradleOpenTelemetry.java:32)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.withOpenTelemetry(GradleOpenTelemetry.java:81)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.callWithSpan(GradleOpenTelemetry.java:31)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.runWithSpan(GradleOpenTelemetry.java:37)
	at com.intellij.gradle.toolingExtension.impl.modelAction.GradleModelFetchAction.doExecute(GradleModelFetchAction.java:130)
	at com.intellij.gradle.toolingExtension.impl.modelAction.GradleModelFetchAction.lambda$execute$1(GradleModelFetchAction.java:111)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.callWithSpan(GradleOpenTelemetry.java:56)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.lambda$callWithSpan$1(GradleOpenTelemetry.java:32)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.withOpenTelemetry(GradleOpenTelemetry.java:81)
	at com.intellij.gradle.toolingExtension.impl.telemetry.GradleOpenTelemetry.callWithSpan(GradleOpenTelemetry.java:31)
	at com.intellij.gradle.toolingExtension.impl.modelAction.GradleModelFetchAction.lambda$execute$2(GradleModelFetchAction.java:110)
	at com.intellij.gradle.toolingExtension.impl.util.GradleExecutorServiceUtil.withSingleThreadExecutor(GradleExecutorServiceUtil.kt:24)
	at com.intellij.gradle.toolingExtension.impl.modelAction.GradleModelFetchAction.execute(GradleModelFetchAction.java:109)
	at com.intellij.gradle.toolingExtension.impl.modelAction.GradleModelFetchAction.execute(GradleModelFetchAction.java:43)
	at org.gradle.tooling.internal.consumer.connection.InternalBuildActionAdapter.execute(InternalBuildActionAdapter.java:66)
	at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner$ActionAdapter.executeAction(AbstractClientProvidedBuildActionRunner.java:108)
	at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner$ActionAdapter.runAction(AbstractClientProvidedBuildActionRunner.java:96)
	at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner$ActionAdapter.fromBuildModel(AbstractClientProvidedBuildActionRunner.java:85)
	at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner$ActionAdapter.fromBuildModel(AbstractClientProvidedBuildActionRunner.java:68)
	at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator.fromBuildModel(DefaultBuildTreeModelCreator.java:66)
	at org.gradle.internal.cc.impl.barrier.BarrierAwareBuildTreeModelCreator.fromBuildModel$lambda$0(BarrierAwareBuildTreeModelCreator.kt:36)
	at org.gradle.internal.cc.impl.barrier.VintageConfigurationTimeActionRunner.runConfigurationTimeAction(VintageConfigurationTimeActionRunner.kt:48)
	at org.gradle.internal.cc.impl.barrier.BarrierAwareBuildTreeModelCreator.fromBuildModel(BarrierAwareBuildTreeModelCreator.kt:35)
	at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.lambda$fromBuildModel$2(DefaultBuildTreeLifecycleController.java:90)
	at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.lambda$runBuild$4(DefaultBuildTreeLifecycleController.java:120)
	at org.gradle.internal.model.StateTransitionController.lambda$transition$6(StateTransitionController.java:179)
	at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:276)
	at org.gradle.internal.model.StateTransitionController.lambda$transition$7(StateTransitionController.java:179)
	at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:45)
	at org.gradle.internal.model.StateTransitionController.transition(StateTransitionController.java:179)
	at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.runBuild(DefaultBuildTreeLifecycleController.java:117)
	at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.fromBuildModel(DefaultBuildTreeLifecycleController.java:82)
	at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner.runClientAction(AbstractClientProvidedBuildActionRunner.java:42)
	at org.gradle.tooling.internal.provider.runner.ClientProvidedPhasedActionRunner.run(ClientProvidedPhasedActionRunner.java:58)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.internal.buildtree.ProblemReportingBuildActionRunner.run(ProblemReportingBuildActionRunner.java:54)
	at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:83)
	at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:135)
	at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:54)
	at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.lambda$execute$0(RootBuildLifecycleBuildActionExecutor.java:101)
	at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:126)
	at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.execute(RootBuildLifecycleBuildActionExecutor.java:101)
	at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.runRootBuildAction(BuildTreeLifecycleBuildActionExecutor.java:98)
	at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.execute(BuildTreeLifecycleBuildActionExecutor.java:69)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$2.call(RunAsBuildOperationBuildActionExecutor.java:65)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$2.call(RunAsBuildOperationBuildActionExecutor.java:61)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor.execute(RunAsBuildOperationBuildActionExecutor.java:61)
	at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.lambda$execute$0(RunAsWorkerThreadBuildActionExecutor.java:36)
	at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
	at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
	at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
	at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.execute(RunAsWorkerThreadBuildActionExecutor.java:36)
	at org.gradle.tooling.internal.provider.continuous.ContinuousBuildActionExecutor.execute(ContinuousBuildActionExecutor.java:110)
	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecutor.execute(SubscribableBuildActionExecutor.java:64)
	at org.gradle.internal.session.DefaultBuildSessionContext.execute(DefaultBuildSessionContext.java:46)
	at org.gradle.internal.buildprocess.execution.BuildSessionLifecycleBuildActionExecutor$ActionImpl.apply(BuildSessionLifecycleBuildActionExecutor.java:106)
	at org.gradle.internal.buildprocess.execution.BuildSessionLifecycleBuildActionExecutor$ActionImpl.apply(BuildSessionLifecycleBuildActionExecutor.java:94)
	at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:73)
	at org.gradle.internal.buildprocess.execution.BuildSessionLifecycleBuildActionExecutor.execute(BuildSessionLifecycleBuildActionExecutor.java:67)
	at org.gradle.internal.buildprocess.execution.BuildSessionLifecycleBuildActionExecutor.execute(BuildSessionLifecycleBuildActionExecutor.java:45)
	at org.gradle.internal.buildprocess.execution.StartParamsValidatingActionExecutor.execute(StartParamsValidatingActionExecutor.java:57)
	at org.gradle.internal.buildprocess.execution.StartParamsValidatingActionExecutor.execute(StartParamsValidatingActionExecutor.java:32)
	at org.gradle.internal.buildprocess.execution.SessionFailureReportingActionExecutor.execute(SessionFailureReportingActionExecutor.java:51)
	at org.gradle.internal.buildprocess.execution.SessionFailureReportingActionExecutor.execute(SessionFailureReportingActionExecutor.java:39)
	at org.gradle.internal.buildprocess.execution.SetupLoggingActionExecutor.execute(SetupLoggingActionExecutor.java:47)
	at org.gradle.internal.buildprocess.execution.SetupLoggingActionExecutor.execute(SetupLoggingActionExecutor.java:31)
	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:70)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.lambda$execute$0(ForwardClientInput.java:40)
	at org.gradle.internal.daemon.clientinput.ClientInputForwarder.forwardInput(ClientInputForwarder.java:80)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:64)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
	at org.gradle.launcher.daemon.server.DaemonStateCoordinator.lambda$runCommand$0(DaemonStateCoordinator.java:321)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
	at java.base@21.0.10/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base@21.0.10/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base@21.0.10/java.lang.Thread.run(Thread.java:1583)
Caused by: org.gradle.api.internal.artifacts.transform.TransformException: Failed to transform gradle-9.3.0-src.zip (gradle:gradle:9.3.0) to match attributes {artifactType=src-directory, org.gradle.status=integration}.
	at org.gradle.api.internal.artifacts.transform.TransformingAsyncArtifactListener$TransformedArtifact.lambda$visit$4(TransformingAsyncArtifactListener.java:256)
	at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:288)
	at org.gradle.api.internal.artifacts.transform.TransformingAsyncArtifactListener$TransformedArtifact.visit(TransformingAsyncArtifactListener.java:248)
	at org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.ParallelResolveArtifactSet$VisitingSet$StartVisitAction.visitResults(ParallelResolveArtifactSet.java:100)
	at org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.ParallelResolveArtifactSet$VisitingSet.visit(ParallelResolveArtifactSet.java:69)
	at org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.ResolvedArtifactSetResolver$1.run(ResolvedArtifactSetResolver.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
	at org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.ResolvedArtifactSetResolver.visitArtifacts(ResolvedArtifactSetResolver.java:65)
	at org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.ResolvedArtifactSetResolver.lambda$visitInUnmanagedWorkerThread$0(ResolvedArtifactSetResolver.java:61)
	at org.gradle.internal.work.DefaultWorkerLeaseService.runAsUnmanagedWorkerThread(DefaultWorkerLeaseService.java:139)
	at org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.ResolvedArtifactSetResolver.visitInUnmanagedWorkerThread(ResolvedArtifactSetResolver.java:61)
	at org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.DefaultSelectedArtifactSet.visitArtifacts(DefaultSelectedArtifactSet.java:59)
	at org.gradle.api.internal.artifacts.configurations.ResolutionResultProviderBackedSelectedArtifactSet.visitArtifacts(ResolutionResultProviderBackedSelectedArtifactSet.java:52)
	at org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.SelectedArtifactSet.visitFiles(SelectedArtifactSet.java:34)
	at org.gradle.api.internal.artifacts.configurations.ResolutionBackedFileCollection.visitContents(ResolutionBackedFileCollection.java:75)
	... 188 more
Caused by: org.gradle.internal.resolve.ArtifactResolveException: Could not download gradle-9.3.0-src.zip (gradle:gradle:9.3.0)
	at org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver$RemoteRepositoryAccess.resolveArtifact(ExternalResourceResolver.java:499)
	at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.CachingModuleComponentRepository$ResolveAndCacheRepositoryAccess.resolveArtifact(CachingModuleComponentRepository.java:470)
	at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ErrorHandlingModuleComponentRepository$ErrorHandlingModuleComponentRepositoryAccess.lambda$resolveArtifact$12(ErrorHandlingModuleComponentRepository.java:180)
	at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ErrorHandlingModuleComponentRepository$ErrorHandlingModuleComponentRepositoryAccess.tryResolveAndMaybeDisable(ErrorHandlingModuleComponentRepository.java:251)
	at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ErrorHandlingModuleComponentRepository$ErrorHandlingModuleComponentRepositoryAccess.performOperationWithRetries(ErrorHandlingModuleComponentRepository.java:204)
	at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ErrorHandlingModuleComponentRepository$ErrorHandlingModuleComponentRepositoryAccess.resolveArtifact(ErrorHandlingModuleComponentRepository.java:178)
	at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainArtifactResolver.resolveArtifactLater(RepositoryChainArtifactResolver.java:75)
	at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainArtifactResolver.lambda$resolveArtifact$0(RepositoryChainArtifactResolver.java:63)
	at org.gradle.internal.model.CalculatedValueContainerFactory$SupplierBackedCalculator.calculateValue(CalculatedValueContainerFactory.java:69)
	at org.gradle.internal.model.CalculatedValueContainer$CalculationState.lambda$attachValue$0(CalculatedValueContainer.java:227)
	at org.gradle.internal.Try.ofFailable(Try.java:46)
	at org.gradle.internal.model.CalculatedValueContainer$CalculationState.attachValue(CalculatedValueContainer.java:222)
	at org.gradle.internal.model.CalculatedValueContainer.finalizeIfNotAlready(CalculatedValueContainer.java:195)
	at org.gradle.internal.model.CalculatedValueContainer.finalizeIfNotAlready(CalculatedValueContainer.java:186)
	at org.gradle.api.internal.artifacts.transform.TransformingAsyncArtifactListener$TransformedArtifact.finalizeValue(TransformingAsyncArtifactListener.java:206)
	at org.gradle.api.internal.artifacts.transform.TransformingAsyncArtifactListener$TransformedArtifact.run(TransformingAsyncArtifactListener.java:160)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$executeInParallel$0(DefaultBuildOperationExecutor.java:102)
	at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.runOperation(DefaultBuildOperationQueue.java:292)
	at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.doRunBatch(DefaultBuildOperationQueue.java:273)
	at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.lambda$runBatch$0(DefaultBuildOperationQueue.java:258)
	at org.gradle.internal.resources.AbstractResourceLockRegistry.whileDisallowingLockChanges(AbstractResourceLockRegistry.java:50)
	at org.gradle.internal.work.DefaultWorkerLeaseService.whileDisallowingProjectLockChanges(DefaultWorkerLeaseService.java:233)
	at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.lambda$runBatch$1(DefaultBuildOperationQueue.java:258)
	at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:125)
	at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.runBatch(DefaultBuildOperationQueue.java:244)
	at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.runOperations(DefaultBuildOperationQueue.java:212)
	at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:84)
	at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.run(DefaultBuildOperationQueue.java:205)
	at org.gradle.internal.operations.DefaultBuildOperationQueue.waitForCompletion(DefaultBuildOperationQueue.java:114)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.executeInParallel(DefaultBuildOperationExecutor.java:115)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.runAll(DefaultBuildOperationExecutor.java:64)
	at org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.ParallelResolveArtifactSet$VisitingSet.visit(ParallelResolveArtifactSet.java:66)
	... 204 more
Caused by: org.gradle.api.resources.ResourceException: Could not get resource 'https://services.gradle.org/distributions/gradle-9.3.0-src.zip'.
	at org.gradle.internal.resource.ResourceExceptions.failure(ResourceExceptions.java:74)
	at org.gradle.internal.resource.ResourceExceptions.getFailed(ResourceExceptions.java:57)
	at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.downloadByCoords(DefaultExternalResourceArtifactResolver.java:154)
	at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.downloadStaticResource(DefaultExternalResourceArtifactResolver.java:94)
	at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.resolveArtifact(DefaultExternalResourceArtifactResolver.java:62)
	at org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver$RemoteRepositoryAccess.resolveArtifact(ExternalResourceResolver.java:492)
	... 239 more
Caused by: org.gradle.internal.resource.transport.http.HttpRequestException: Could not GET 'https://services.gradle.org/distributions/gradle-9.3.0-src.zip'.
	at org.gradle.internal.resource.transport.http.HttpClientHelper.createHttpRequestException(HttpClientHelper.java:123)
	at org.gradle.internal.resource.transport.http.HttpClientHelper.performRequest(HttpClientHelper.java:117)
	at org.gradle.internal.resource.transport.http.HttpClientHelper.performRawGet(HttpClientHelper.java:99)
	at org.gradle.internal.resource.transport.http.HttpClientHelper.performGet(HttpClientHelper.java:104)
	at org.gradle.internal.resource.transport.http.HttpResourceAccessor.openResource(HttpResourceAccessor.java:45)
	at org.gradle.internal.resource.transport.http.HttpResourceAccessor.openResource(HttpResourceAccessor.java:30)
	at org.gradle.internal.resource.transfer.AbstractExternalResourceAccessor.withContent(AbstractExternalResourceAccessor.java:32)
	at org.gradle.internal.resource.transfer.DefaultExternalResourceConnector.withContent(DefaultExternalResourceConnector.java:59)
	at org.gradle.internal.resource.transfer.ProgressLoggingExternalResourceAccessor$DownloadOperation.call(ProgressLoggingExternalResourceAccessor.java:136)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.resource.transfer.ProgressLoggingExternalResourceAccessor.withContent(ProgressLoggingExternalResourceAccessor.java:49)
	at org.gradle.internal.resource.transfer.AccessorBackedExternalResource.withContentIfPresent(AccessorBackedExternalResource.java:103)
	at org.gradle.internal.resource.transfer.DefaultCacheAwareExternalResourceAccessor.copyToCache(DefaultCacheAwareExternalResourceAccessor.java:188)
	at org.gradle.internal.resource.transfer.DefaultCacheAwareExternalResourceAccessor.lambda$getResource$1(DefaultCacheAwareExternalResourceAccessor.java:86)
	at org.gradle.cache.internal.ProducerGuard$AdaptiveProducerGuard.guardByKey(ProducerGuard.java:97)
	at org.gradle.internal.resource.transfer.DefaultCacheAwareExternalResourceAccessor.getResource(DefaultCacheAwareExternalResourceAccessor.java:80)
	at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.downloadByCoords(DefaultExternalResourceArtifactResolver.java:149)
	... 242 more
Caused by: java.net.UnknownHostException: services.gradle.org: nodename nor servname provided, or not known
	at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
	at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:52)
	at java.base/java.net.InetAddress$PlatformResolver.lookupByName(InetAddress.java:1211)
	at java.base/java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1828)
	at java.base/java.net.InetAddress$NameServiceAddresses.get(InetAddress.java:1139)
	at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1818)
	at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1688)
	at org.apache.http.impl.conn.SystemDefaultDnsResolver.resolve(SystemDefaultDnsResolver.java:45)
	at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:112)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
	at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.gradle.internal.resource.transport.http.HttpClientHelper.performHttpRequest(HttpClientHelper.java:200)
	at org.gradle.internal.resource.transport.http.HttpClientHelper.performHttpRequest(HttpClientHelper.java:176)
	at org.gradle.internal.resource.transport.http.HttpClientHelper.executeGetOrHead(HttpClientHelper.java:165)
	at org.gradle.internal.resource.transport.http.HttpClientHelper.performRequest(HttpClientHelper.java:113)
	... 263 more

foo

foo/build.gradle.kts
import org.gradle.api.internal.project.ProjectInternal
import org.gradle.internal.file.PathTraversalChecker.safePathName
import java.io.InputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipFile

abstract class FindGradleSources : TransformAction<TransformParameters.None> {

    @get:PathSensitive(PathSensitivity.NONE)
    @get:InputArtifact
    abstract val input: Provider<FileSystemLocation>

    override fun transform(outputs: TransformOutputs) {
        ZipFile(input.get().asFile).use { zip ->
            val it = zip.entries()
            if (!it.hasMoreElements()) {
                // Zip contains no files.
                return
            }

            // We assume the zip contains a single root directory
            val first = it.nextElement()
            val slashIndex = first.name.indexOf('/')
            if (slashIndex < 0) {
                // Zip contains no root directory.
                return
            }
            val rootPrefix = first.name.substring(0, slashIndex + 1)

            val projectOutputs = ProjectSourceOutputs(outputs)
            processEntry(rootPrefix, projectOutputs, first, zip)
            while (it.hasMoreElements()) {
                processEntry(rootPrefix, projectOutputs, it.nextElement(), zip)
            }
        }
    }

    private fun processEntry(prefix: String, outputs: ProjectSourceOutputs, entry: ZipEntry, zip: ZipFile) {
        val rootOffset = consume(prefix, 0, entry)
        if (rootOffset == -1) {
            // Entry not under root directory.
            return
        }

        val subprojectsOffset = consume("subprojects/", rootOffset, entry)
        if (subprojectsOffset != -1) {
            processProjectEntry(subprojectsOffset, outputs, entry, zip)
            return
        }

        val platformsOffset = consume("platforms/", rootOffset, entry)
        if (platformsOffset != -1) {
            val platformDirOffset = consumeDir(platformsOffset, entry)
            if (platformDirOffset != -1) {
                processProjectEntry(platformDirOffset, outputs, entry, zip)
            }
            return
        }
    }

    private fun processProjectEntry(offset: Int, outputs: ProjectSourceOutputs, entry: ZipEntry, zip: ZipFile) {
        // Offset marks the beginning of the project directory name
        val projectNameOffset = consumeDir(offset, entry)
        if (projectNameOffset == -1) {
            return
        }

        val srcMainOffset = consume("src/main/", projectNameOffset, entry)
        if (srcMainOffset == -1) {
            return
        }

        val sourceDirectoryOffset = consumeDir(srcMainOffset, entry)
        if (sourceDirectoryOffset == -1 || entry.isDirectory) {
            return
        }

        val projectName = entry.name.substring(offset, projectNameOffset - 1)
        val projectSrcOutputDir = outputs.dir(projectName)
        val output = projectSrcOutputDir.resolve(safePathName(entry.name.substring(sourceDirectoryOffset)))

        zip.getInputStream(entry).writeTo(output)
    }

    private fun InputStream.writeTo(output: File) {
        output.parentFile.mkdirs()
        use { input ->
            output.outputStream().use { output ->
                input.copyTo(output)
            }
        }
    }

    fun consumeDir(offset: Int, entry: ZipEntry): Int {
        val dirIndex = entry.name.indexOf('/', offset)
        if (dirIndex >= 0) {
            return dirIndex + 1
        }

        return -1
    }

    fun consume(toSkip: String, offset: Int, entry: ZipEntry): Int {
        if (entry.name.startsWith(toSkip, offset)) {
            return offset + toSkip.length
        }

        return -1
    }

    class ProjectSourceOutputs(private val outputs: TransformOutputs, private val dirs: MutableMap<String, File> = mutableMapOf()) {
        fun dir(name: String): File {
            val dir = dirs[name]
            if (dir != null) {
                return dir
            }
            return outputs.dir(name).also { dirs[name] = it }
        }
    }

}


var customResolver = (project as ProjectInternal).newDetachedResolver()
customResolver.repositories.ivy {
    name = "Gradle distributions mirror"
    setUrl("https://mirrors.cloud.tencent.com/gradle/")
    metadataSources {
        artifact()
    }
    patternLayout {
        artifact("[module]-[revision](-[classifier])(.[ext])")
    }
}
customResolver.dependencies.registerTransform(FindGradleSources::class) {
    from.attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, "zip")
    to.attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, "src-directory")
}

val config: Configuration = customResolver.configurations.detachedConfiguration(
    dependencies.create("gradle:gradle:${gradle.gradleVersion}") {
        artifact {
            classifier = "src"
            type = "zip"
        }
    }).apply { attributes.attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, "src-directory") }

val resolvedFiles = config.resolve()
println(">>> Resolved ${resolvedFiles.size} files")

cache

BTreePersistentIndexedCache
package org.gradle.cache.internal.btree;

public class BTreePersistentIndexedCache<K, V> {}


    private class DataBlock extends BlockPayload {
        private int size;
        private StreamByteBuffer buffer;
        private V value;

        private DataBlock() {
        }

        public DataBlock(V value) throws Exception {
            this.value = value;
            setValue(value);
            size = buffer.totalBytesUnread();
        }

        public DataBlock(V value, StreamByteBuffer buffer) throws Exception {
            this.value = value;
            this.buffer = buffer;
            size = buffer.totalBytesUnread();
        }

        public void setValue(V value) throws Exception {
            buffer = StreamByteBuffer.createWithChunkSizeInDefaultRange(size);
            KryoBackedEncoder encoder = new KryoBackedEncoder(buffer.getOutputStream());
            serializer.write(encoder, value);
            encoder.flush();
        }

        public V getValue() throws Exception {
            if (value == null) {
                value = serializer.read(new KryoBackedDecoder(buffer.getInputStream()));
                buffer = null;
            }
            return value;
        }

        @Override
        protected byte getType() {
            return 0x33;
        }

        @Override
        protected int getSize() {
            return 2 * Block.INT_SIZE + size;
        }

        @Override
        public void read(DataInputStream instr) throws Exception {
            size = instr.readInt();
            int bytes = instr.readInt();
            buffer = StreamByteBuffer.of(instr, bytes);
        }

        @Override
        public void write(DataOutputStream outstr) throws Exception {
            outstr.writeInt(size);
            outstr.writeInt(buffer.totalBytesUnread());
            buffer.writeTo(outstr);
            buffer = null;
        }

        public DataBlockUpdateResult useNewValue(V value) throws Exception {
            setValue(value);
            boolean ok = buffer.totalBytesUnread() <= size;
            if (ok) {
                this.value = value;
                store.write(this);
                return DataBlockUpdateResult.success();
            } else {
                return DataBlockUpdateResult.failed(buffer);
            }
        }
    }
gradle/dependency-management/DependencyManagementBuildTreeScopeServices
package org.gradle.api.internal.artifacts;
 
class DependencyManagementBuildTreeScopeServices implements ServiceRegistrationProvider {
    ...
        
    private ByUrlCachedExternalResourceIndex prepareArtifactUrlCachedResolutionIndex(BuildCommencedTimeProvider timeProvider, ArtifactCacheLockingAccessCoordinator cacheAccessCoordinator, ExternalResourceFileStore externalResourceFileStore, ArtifactCacheMetadata artifactCacheMetadata) {
        return new ByUrlCachedExternalResourceIndex(
            "resource-at-url",
            timeProvider,
            cacheAccessCoordinator,
            externalResourceFileStore.getFileAccessTracker(),
            artifactCacheMetadata.getCacheDir().toPath()
        );
    }
    
    @Provides
    FileStoreAndIndexProvider createFileStoreAndIndexProvider(
        BuildCommencedTimeProvider timeProvider,
        ArtifactCachesProvider artifactCaches,
        DefaultExternalResourceFileStore.Factory defaultExternalResourceFileStoreFactory,
        DefaultArtifactIdentifierFileStore.Factory defaultArtifactIdentifierFileStoreFactory
    ) {
        ExternalResourceFileStore writableFileStore = defaultExternalResourceFileStoreFactory.create(artifactCaches.getWritableCacheMetadata());
        ExternalResourceFileStore externalResourceFileStore = artifactCaches.withReadOnlyCache((md, manager) ->
            (ExternalResourceFileStore) new TwoStageExternalResourceFileStore(defaultExternalResourceFileStoreFactory.create(md), writableFileStore)).orElse(writableFileStore);
        CachedExternalResourceIndex<String> writableByUrlCachedExternalResourceIndex = prepareArtifactUrlCachedResolutionIndex(timeProvider, artifactCaches.getWritableCacheAccessCoordinator(), externalResourceFileStore, artifactCaches.getWritableCacheMetadata());
        ArtifactIdentifierFileStore writableArtifactIdentifierFileStore = artifactCaches.withWritableCache((md, manager) -> defaultArtifactIdentifierFileStoreFactory.create(md));
        ArtifactIdentifierFileStore artifactIdentifierFileStore = artifactCaches.withReadOnlyCache((md, manager) -> (ArtifactIdentifierFileStore) new TwoStageArtifactIdentifierFileStore(
            defaultArtifactIdentifierFileStoreFactory.create(md),
            writableArtifactIdentifierFileStore
        )).orElse(writableArtifactIdentifierFileStore);
        return new FileStoreAndIndexProvider(
            artifactCaches.withReadOnlyCache((md, manager) -> (CachedExternalResourceIndex<String>) new TwoStageByUrlCachedExternalResourceIndex(md.getCacheDir().toPath(), prepareArtifactUrlCachedResolutionIndex(timeProvider, manager, externalResourceFileStore, md), writableByUrlCachedExternalResourceIndex)).orElse(writableByUrlCachedExternalResourceIndex),
            externalResourceFileStore, artifactIdentifierFileStore);
    }
 
}
gradle/dependency-management/ByUrlCachedExternalResourceIndex
package org.gradle.internal.resource.cached;
 
public class ByUrlCachedExternalResourceIndex extends DefaultCachedExternalResourceIndex<String> {
    public ByUrlCachedExternalResourceIndex(String persistentCacheFile, BuildCommencedTimeProvider timeProvider, ArtifactCacheLockingAccessCoordinator cacheAccessCoordinator, FileAccessTracker fileAccessTracker, Path commonRootPath) {
        super(persistentCacheFile, BaseSerializerFactory.STRING_SERIALIZER, timeProvider, cacheAccessCoordinator, fileAccessTracker, commonRootPath);
    }
}
DefaultCachedExternalResourceIndex
package org.gradle.internal.resource.cached;
 
public class DefaultCachedExternalResourceIndex<K extends Serializable> extends AbstractCachedIndex<K, CachedExternalResource> implements CachedExternalResourceIndex<K> {
    private final BuildCommencedTimeProvider timeProvider;
 
    public DefaultCachedExternalResourceIndex(String persistentCacheFile, Serializer<K> keySerializer, BuildCommencedTimeProvider timeProvider, ArtifactCacheLockingAccessCoordinator cacheAccessCoordinator, FileAccessTracker fileAccessTracker, Path commonRootPath) {
        super(persistentCacheFile, keySerializer, new CachedExternalResourceSerializer(commonRootPath), cacheAccessCoordinator, fileAccessTracker);
        this.timeProvider = timeProvider;
    }
 
    private DefaultCachedExternalResource createEntry(File artifactFile, ExternalResourceMetaData externalResourceMetaData) {
        return new DefaultCachedExternalResource(artifactFile, timeProvider.getCurrentTime(), externalResourceMetaData);
    }
 
    @Override
    public void store(final K key, final File artifactFile, ExternalResourceMetaData externalResourceMetaData) {
        assertArtifactFileNotNull(artifactFile);
        assertKeyNotNull(key);
 
        storeInternal(key, createEntry(artifactFile, externalResourceMetaData));
    }
 
    @Override
    public void storeMissing(K key) {
        storeInternal(key, new DefaultCachedExternalResource(timeProvider.getCurrentTime()));
    }
 
    @VisibleForTesting
    static class CachedExternalResourceSerializer implements Serializer<CachedExternalResource> {
        private final Path commonRootPath;
 
        public CachedExternalResourceSerializer(Path commonRootPath) {
            this.commonRootPath = commonRootPath;
        }
 
        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            CachedExternalResourceSerializer that = (CachedExternalResourceSerializer) o;
            return commonRootPath.equals(that.commonRootPath);
        }
 
        @Override
        public int hashCode() {
            return commonRootPath.hashCode();
        }
 
        @Override
        public CachedExternalResource read(Decoder decoder) throws Exception {
            File cachedFile = null;
            if (decoder.readBoolean()) {
                cachedFile = denormalizeAndResolveFilePath(decoder.readString());
            }
            long cachedAt = decoder.readLong();
            ExternalResourceMetaData metaData = null;
            if (decoder.readBoolean()) {
                URI uri = new URI(decoder.readString());
                long lastModified = 0;
                if (decoder.readBoolean()) {
                    lastModified = decoder.readLong();
                }
                String contentType = decoder.readNullableString();
                long contentLength = decoder.readSmallLong();
                String etag = decoder.readNullableString();
                HashCode sha1 = null;
                if (decoder.readBoolean()) {
                    sha1 = HashCode.fromString(decoder.readString());
                }
                metaData = new DefaultExternalResourceMetaData(uri, lastModified, contentLength, contentType, etag, sha1);
            }
            return new DefaultCachedExternalResource(cachedFile, cachedAt, metaData);
        }
 
        @Override
        public void write(Encoder encoder, CachedExternalResource value) throws Exception {
            encoder.writeBoolean(value.getCachedFile() != null);
            if (value.getCachedFile() != null) {
                encoder.writeString(relativizeAndNormalizeFilePath(value.getCachedFile()));
            }
            encoder.writeLong(value.getCachedAt());
            ExternalResourceMetaData metaData = value.getExternalResourceMetaData();
            encoder.writeBoolean(metaData != null);
            if (metaData != null) {
                encoder.writeString(metaData.getLocation().toASCIIString());
                encoder.writeBoolean(metaData.getLastModified() != null);
                if (metaData.getLastModified() != null) {
                    encoder.writeLong(metaData.getLastModified().getTime());
                }
                encoder.writeNullableString(metaData.getContentType());
                encoder.writeSmallLong(metaData.getContentLength());
                encoder.writeNullableString(metaData.getEtag());
                encoder.writeBoolean(metaData.getSha1() != null);
                if (metaData.getSha1() != null) {
                    encoder.writeString(metaData.getSha1().toString());
                }
            }
        }
 
        private String relativizeAndNormalizeFilePath(File cachedFile) {
            Path filePath = cachedFile.toPath();
            assert filePath.startsWith(commonRootPath) : "Attempting to cache file " + filePath + " not in " + commonRootPath;
            String systemDependentPath = commonRootPath.relativize(filePath).toString();
            if (!filePath.getFileSystem().getSeparator().equals("/")) {
                return systemDependentPath.replace(filePath.getFileSystem().getSeparator(), "/");
            }
            return systemDependentPath;
        }
 
        private File denormalizeAndResolveFilePath(String relativePath) throws IOException {
            if (!commonRootPath.getFileSystem().getSeparator().equals("/")) {
                relativePath = relativePath.replace("/", commonRootPath.getFileSystem().getSeparator());
            }
            return commonRootPath.resolve(relativePath).toFile();
        }
 
    }
}

 

posted @ 2026-04-12 22:19  UPeRVv  阅读(6)  评论(0)    收藏  举报