From 6c9064ac4ff312dc0e4040047cc73a44407bedb1 Mon Sep 17 00:00:00 2001 From: RB1248 Date: Thu, 16 Jul 2026 23:56:22 -0400 Subject: [PATCH 1/6] working solution --- foojay-resolver/build.gradle.kts | 6 ++ ...actFoojayToolchainsPluginFunctionalTest.kt | 48 ++++++++- .../FoojayToolchainsPluginFunctionalTest.kt | 53 ++++++++++ .../org/gradle/toolchains/foojay/FoojayApi.kt | 97 ++++++++++++------- .../toolchains/foojay/FoojayApiService.kt | 19 ++++ .../foojay/FoojayApiServiceBridge.kt | 16 +++ .../toolchains/foojay/FoojayExtension.kt | 24 +++++ .../foojay/FoojayToolchainResolver.kt | 6 +- .../foojay/FoojayToolchainsPlugin.kt | 21 ++-- .../gradle/toolchains/foojay/FoojayApiTest.kt | 2 +- gradle/libs.versions.toml | 1 + 11 files changed, 245 insertions(+), 48 deletions(-) create mode 100644 foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiService.kt create mode 100644 foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiServiceBridge.kt create mode 100644 foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayExtension.kt diff --git a/foojay-resolver/build.gradle.kts b/foojay-resolver/build.gradle.kts index c6d71fa..9435139 100644 --- a/foojay-resolver/build.gradle.kts +++ b/foojay-resolver/build.gradle.kts @@ -102,8 +102,14 @@ signing { testing { suites { val functionalTest by registering(JvmTestSuite::class) { + targets.all { + testTask.configure { + testLogging.showStandardStreams = true + } + } dependencies { implementation("org.jetbrains.kotlin:kotlin-test-junit5") + implementation(libs.littleproxy) } } val test by getting(JvmTestSuite::class) { diff --git a/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/AbstractFoojayToolchainsPluginFunctionalTest.kt b/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/AbstractFoojayToolchainsPluginFunctionalTest.kt index 06f957e..db23290 100644 --- a/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/AbstractFoojayToolchainsPluginFunctionalTest.kt +++ b/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/AbstractFoojayToolchainsPluginFunctionalTest.kt @@ -1,11 +1,21 @@ package org.gradle.toolchains.foojay +import io.netty.handler.codec.http.HttpObject +import io.netty.handler.codec.http.HttpRequest +import io.netty.handler.codec.http.HttpResponse import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.GradleRunner import org.gradle.testkit.runner.TaskOutcome +import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.io.TempDir +import org.littleshoot.proxy.HttpFilters +import org.littleshoot.proxy.HttpFiltersAdapter +import org.littleshoot.proxy.HttpFiltersSourceAdapter +import org.littleshoot.proxy.HttpProxyServer +import org.littleshoot.proxy.impl.DefaultHttpProxyServer import java.io.File +import java.util.concurrent.atomic.AtomicInteger import kotlin.test.assertTrue abstract class AbstractFoojayToolchainsPluginFunctionalTest { @@ -16,6 +26,10 @@ abstract class AbstractFoojayToolchainsPluginFunctionalTest { @field:TempDir protected lateinit var homeDir: File + protected lateinit var proxyServer: HttpProxyServer + protected var proxyPort: Int = 0 + protected val proxyInterceptorCount = AtomicInteger(0) + private val settingsFile by lazy { projectDir.resolve("settings.gradle.kts") } private val propertiesFile by lazy { projectDir.resolve("gradle.properties") } private val buildFile by lazy { projectDir.resolve("build.gradle.kts") } @@ -27,9 +41,39 @@ abstract class AbstractFoojayToolchainsPluginFunctionalTest { org.gradle.java.installations.auto-detect=false org.gradle.java.installations.auto-download=true """.trimIndent()) + // Start proxy on a random available port + proxyInterceptorCount.set(0) + proxyServer = DefaultHttpProxyServer.bootstrap() + .withPort(0) + .withFiltersSource(object : HttpFiltersSourceAdapter() { + override fun filterRequest(originalRequest: HttpRequest): HttpFilters { + return object : HttpFiltersAdapter(originalRequest) { + override fun clientToProxyRequest(httpObject: HttpObject): HttpResponse? { + // Increment whenever the proxy intercepts a request frame + if (httpObject is HttpRequest) { + System.err.println("Captured traffic in proxy!") + proxyInterceptorCount.incrementAndGet() + } + return null // Continue normal routing + } + } + } + }) + .start() + proxyPort = proxyServer.listenAddress.port } - protected fun runner(settings: String, buildScript: String): GradleRunner { + @AfterEach + internal fun tearDownProxy() { + proxyServer.stop() + } + + protected fun runner( + settings: String, + buildScript: String, + extraArguments: List = emptyList() + ): GradleRunner { + settingsFile.writeText(settings) buildFile.writeText(buildScript.trimIndent()) @@ -46,7 +90,7 @@ abstract class AbstractFoojayToolchainsPluginFunctionalTest { return GradleRunner.create() .forwardOutput() .withPluginClasspath() - .withArguments(listOf("--info", "-g", homeDir.absolutePath, "compileJava")) + .withArguments(listOf("--info", "-g", homeDir.absolutePath, "compileJava") + extraArguments) .withProjectDir(projectDir) } diff --git a/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPluginFunctionalTest.kt b/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPluginFunctionalTest.kt index 12befa8..c59b369 100644 --- a/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPluginFunctionalTest.kt +++ b/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPluginFunctionalTest.kt @@ -1,7 +1,9 @@ package org.gradle.toolchains.foojay +import org.gradle.internal.classpath.Instrumented.systemProperty import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource +import java.io.PrintWriter import kotlin.test.Test import kotlin.test.assertTrue @@ -43,6 +45,57 @@ class FoojayToolchainsPluginFunctionalTest: AbstractFoojayToolchainsPluginFuncti assertProvisioningSuccessful(result) } + @ParameterizedTest(name = "gradle version: {0}") + @MethodSource("getGradleTestVersions") + fun `can use base plugin with proxy`(gradleVersion: String) { + val settings = """ + plugins { + id("org.gradle.toolchains.foojay-resolver") + } + + // This is the only syntax compatible with version 7.6 to current (9.8). + configure { + proxy { + autoDetect.set(true) + } + } + + toolchainManagement { + jvm { + javaRepositories { + repository("foojay") { + resolverClass.set(org.gradle.toolchains.foojay.FoojayToolchainResolver::class.java) + } + } + } + } + """.trimIndent() + + val buildScript = """ + plugins { + java + } + + java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(${getDifferentJavaVersion()})) + } + } + """ + val arguments = listOf( + "-Dhttps.proxyHost=127.0.0.1", + "-Dhttps.proxyPort=$proxyPort", + "-Dhttps.nonProxyHosts=''", + // To make sure Gradle does not pick up local JDK installations. + "-Porg.gradle.java.installations.auto-detect=false" + ) + val result = runner(settings, buildScript, arguments) + .withGradleVersion(gradleVersion) + .build() + assertProvisioningSuccessful(result) + assertTrue(proxyInterceptorCount.get() > 0, "Traffic bypassed the proxy.") + } + @Test fun `generates useful error for unsupported Gradle versions`() { val settings = """ diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt index 423802d..7d2ad03 100644 --- a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt +++ b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt @@ -1,24 +1,27 @@ package org.gradle.toolchains.foojay import org.gradle.api.GradleException +import org.gradle.api.logging.Logger import org.gradle.jvm.toolchain.JavaLanguageVersion import org.gradle.jvm.toolchain.JvmImplementation import org.gradle.jvm.toolchain.JvmVendorSpec import org.gradle.platform.Architecture import org.gradle.platform.OperatingSystem -import java.io.BufferedReader -import java.io.InputStream -import java.net.HttpURLConnection -import java.net.URL +import org.slf4j.LoggerFactory +import java.net.ProxySelector +import java.net.URI import java.net.URLEncoder +import java.net.http.HttpClient +import java.net.http.HttpRequest +import java.net.http.HttpResponse import java.nio.charset.StandardCharsets.UTF_8 -import java.util.concurrent.TimeUnit.SECONDS +import java.time.Duration +import kotlin.jvm.java @Suppress("MagicNumber") -private val CONNECT_TIMEOUT = SECONDS.toMillis(10).toInt() - +private val CONNECT_TIMEOUT = Duration.ofSeconds(10) @Suppress("MagicNumber") -private val READ_TIMEOUT = SECONDS.toMillis(20).toInt() +private val READ_TIMEOUT = Duration.ofSeconds(20) private const val SCHEMA = "https" @@ -26,11 +29,38 @@ private const val ENDPOINT_ROOT = "api.foojay.io/disco/v3.0" private const val DISTRIBUTIONS_ENDPOINT = "$ENDPOINT_ROOT/distributions" private const val PACKAGES_ENDPOINT = "$ENDPOINT_ROOT/packages" -@Suppress("UnstableApiUsage") -class FoojayApi { +class FoojayApiConfig { + val proxy = ProxyConfig() + class ProxyConfig { + var autoDetect: Boolean = false + } +} +@Suppress("UnstableApiUsage") +class FoojayApi( + private val configs: FoojayApiConfig +) { + private val logger = LoggerFactory.getLogger(FoojayApi::class.java) private val distributions = mutableListOf() + private val httpClient = HttpClient.newBuilder() + .also { builder -> + // Only active the default ProxySelector when plugin configuration `detectProxy` is true + // to keep default plugin behavior. + // The default behavior is to ignore proxy configuration so that it won't introduce side effects if + // this plugin is run in an environment where proxy configurations are defined and that it is not + // expected that the project using this plugin uses the proxy. + if (configs.proxy.autoDetect) { + // Configures the system-wide proxy selector. + builder.proxy(ProxySelector.getDefault()) + } else { + //builder.proxy(HttpClient.Builder.NO_PROXY) + builder.proxy(ProxySelector.getDefault()) + } + builder.connectTimeout(CONNECT_TIMEOUT) + } + .build() + @Suppress("LongParameterList") fun toPackage( version: JavaLanguageVersion, @@ -53,13 +83,10 @@ class FoojayApi { private fun fetchDistributionsIfMissing() { if (distributions.isEmpty()) { - val con = createConnection( + val json = downloadVendorList( DISTRIBUTIONS_ENDPOINT, mapOf("include_versions" to "true", "include_synonyms" to "true") ) - val json = readResponse(con) - con.disconnect() - distributions.addAll(parseDistributions(json)) } } @@ -70,8 +97,7 @@ class FoojayApi { distributionName == "graalvm" -> "version" else -> "jdk_version" } - - val con = createConnection( + val json = downloadVendorList( PACKAGES_ENDPOINT, mapOf( versionApiKey to "$version", @@ -81,21 +107,28 @@ class FoojayApi { "directly_downloadable" to "true" ) ) - val json = readResponse(con) - con.disconnect() - val packages = parsePackages(json) return match(packages, architecture) } - private fun createConnection(endpoint: String, parameters: Map): HttpURLConnection { - val url = URL("$SCHEMA://$endpoint?${toParameterString(parameters)}") - val con = url.openConnection() as HttpURLConnection - con.setRequestProperty("Content-Type", "application/json") - con.requestMethod = "GET" - con.connectTimeout = CONNECT_TIMEOUT - con.readTimeout = READ_TIMEOUT - return con + @Suppress("MagicNumber") + private fun downloadVendorList( + endpoint: String, + params: Map + ): String { + val uri = URI.create("$SCHEMA://$endpoint?${toParameterString(params)}") + System.err.println("👉 Making http request to: $uri") + val request = HttpRequest.newBuilder() + .uri(uri) + .header("Content-Type", "application/json") + .timeout(READ_TIMEOUT) + .GET() + .build() + val response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()) + if (response.statusCode() != 200) { + throw GradleException("Requesting vendor list failed: ${response.body()}") + } + return response.body() } private fun toParameterString(params: Map): String { @@ -103,14 +136,4 @@ class FoojayApi { "${URLEncoder.encode(it.key, UTF_8.name())}=${URLEncoder.encode(it.value, UTF_8.name())}" } } - - private fun readResponse(con: HttpURLConnection): String { - val status = con.responseCode - if (status != HttpURLConnection.HTTP_OK) { - throw GradleException("Requesting vendor list failed: ${readContent(con.errorStream)}") - } - return readContent(con.inputStream) - } - - private fun readContent(stream: InputStream) = stream.bufferedReader().use(BufferedReader::readText) } diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiService.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiService.kt new file mode 100644 index 0000000..214db5d --- /dev/null +++ b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiService.kt @@ -0,0 +1,19 @@ +package org.gradle.toolchains.foojay + +import org.gradle.api.provider.Property +import org.gradle.api.services.BuildService +import org.gradle.api.services.BuildServiceParameters + +interface FoojayApiParameters : BuildServiceParameters { + val detectProxy: Property + + fun toConfigs(): FoojayApiConfig { + return FoojayApiConfig().apply { + proxy.autoDetect = detectProxy.get() + } + } +} + +abstract class FoojayApiService : BuildService { + val api = FoojayApi(parameters.toConfigs()) +} diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiServiceBridge.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiServiceBridge.kt new file mode 100644 index 0000000..0db381e --- /dev/null +++ b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiServiceBridge.kt @@ -0,0 +1,16 @@ +package org.gradle.toolchains.foojay + +import org.gradle.api.provider.Provider + + +object FoojayApiServiceBridge { + private var serviceProvider: Provider? = null + + fun init(serviceProvider: Provider) { + this.serviceProvider = serviceProvider + } + + fun getService(): FoojayApiService? { + return serviceProvider?.orNull + } +} \ No newline at end of file diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayExtension.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayExtension.kt new file mode 100644 index 0000000..c40ce43 --- /dev/null +++ b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayExtension.kt @@ -0,0 +1,24 @@ +package org.gradle.toolchains.foojay + +import org.gradle.api.Action +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Property +import javax.inject.Inject + +@Suppress("UnusedPrivateProperty") +abstract class ProxyConfig @Inject constructor(objects: ObjectFactory) { + abstract val autoDetect: Property + + init { + autoDetect.convention(false) + } +} + +abstract class FoojayExtension @Inject constructor(objectFactory: ObjectFactory) { + + val proxy: ProxyConfig = objectFactory.newInstance(ProxyConfig::class.java) + + fun proxy(action: Action) { + action.execute(proxy) + } +} diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainResolver.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainResolver.kt index f44eefe..5d903c2 100644 --- a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainResolver.kt +++ b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainResolver.kt @@ -8,9 +8,11 @@ import org.gradle.jvm.toolchain.JavaToolchainSpec import org.gradle.util.GradleVersion import java.util.* +@Suppress("UnstableApiUsage") abstract class FoojayToolchainResolver : JavaToolchainResolver { - private val api: FoojayApi = FoojayApi() + private val apiService = FoojayApiServiceBridge.getService() + ?: throw RuntimeException("failed to retrieve FoojayApiService instance") override fun resolve(request: JavaToolchainRequest): Optional { val spec = request.javaToolchainSpec @@ -20,7 +22,7 @@ abstract class FoojayToolchainResolver : JavaToolchainResolver { false } val platform = request.buildPlatform - val links = api.toPackage( + val links = apiService.api.toPackage( spec.languageVersion.get(), spec.vendor.get(), spec.implementation.get(), diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPlugin.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPlugin.kt index b63a7c4..0e713dd 100644 --- a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPlugin.kt +++ b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPlugin.kt @@ -6,9 +6,13 @@ package org.gradle.toolchains.foojay import org.gradle.api.initialization.Settings import org.gradle.api.internal.SettingsInternal import org.gradle.jvm.toolchain.JavaToolchainResolverRegistry +import org.gradle.kotlin.dsl.support.serviceOf import org.gradle.util.GradleVersion -@Suppress("unused") +private const val FOOJAY_EXTENSION_NAME = "foojay" +private const val FOOJAY_API_SERVICE_NAME = "foojayApi" + +@Suppress("unused", "UnstableApiUsage") abstract class FoojayToolchainsPlugin: AbstractFoojayToolchainPlugin() { @Suppress("TooGenericExceptionThrown") @@ -16,11 +20,16 @@ abstract class FoojayToolchainsPlugin: AbstractFoojayToolchainPlugin() { if (GradleVersion.current().baseVersion < GradleVersion.version("7.6")) { throw RuntimeException("${FoojayToolchainsPlugin::class.simpleName} needs Gradle version 7.6 or higher") } - + val extension = settings.extensions.create(FOOJAY_EXTENSION_NAME, FoojayExtension::class.java) + val service = settings.gradle.sharedServices.registerIfAbsent( + FOOJAY_API_SERVICE_NAME, + FoojayApiService::class.java + ) { + this.parameters.detectProxy.set(extension.proxy.autoDetect) + } + FoojayApiServiceBridge.init(service) settings.plugins.apply("jvm-toolchain-management") - - val registry = (settings as SettingsInternal).services.get(JavaToolchainResolverRegistry::class.java) - registry.register(FoojayToolchainResolver::class.java) + settings.serviceOf() + .apply { register(FoojayToolchainResolver::class.java) } } - } diff --git a/foojay-resolver/src/test/kotlin/org/gradle/toolchains/foojay/FoojayApiTest.kt b/foojay-resolver/src/test/kotlin/org/gradle/toolchains/foojay/FoojayApiTest.kt index 9ac4c77..7767558 100644 --- a/foojay-resolver/src/test/kotlin/org/gradle/toolchains/foojay/FoojayApiTest.kt +++ b/foojay-resolver/src/test/kotlin/org/gradle/toolchains/foojay/FoojayApiTest.kt @@ -21,7 +21,7 @@ import kotlin.test.assertTrue @Suppress("UnstableApiUsage") class FoojayApiTest { - private val api = FoojayApi() + private val api = FoojayApi(FoojayApiConfig()) @ParameterizedTest(name = "javaVersion: {0}, vendor: {1}, isJ9: {2}, os: {3}, arch: {4}") @MethodSource("getData") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 27306c0..4fc7d05 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,6 +2,7 @@ [libraries] gson = { module = "com.google.code.gson:gson", version = "2.14.0" } +littleproxy = { module = "io.github.littleproxy:littleproxy", version = "2.7.0" } [plugins] plugin-publish = { id = "com.gradle.plugin-publish", version = "2.1.1" } From 909acac1382b48c7679fa3e5e552b2b8f35f6d37 Mon Sep 17 00:00:00 2001 From: RB1248 Date: Fri, 17 Jul 2026 00:26:28 -0400 Subject: [PATCH 2/6] simplified everything --- ...actFoojayToolchainsPluginFunctionalTest.kt | 3 +- .../FoojayToolchainsPluginFunctionalTest.kt | 59 +++++++++++++++---- .../org/gradle/toolchains/foojay/FoojayApi.kt | 31 ++-------- .../toolchains/foojay/FoojayApiService.kt | 19 ------ .../foojay/FoojayApiServiceBridge.kt | 16 ----- .../toolchains/foojay/FoojayExtension.kt | 24 -------- .../foojay/FoojayToolchainResolver.kt | 5 +- .../foojay/FoojayToolchainsPlugin.kt | 12 ---- 8 files changed, 55 insertions(+), 114 deletions(-) delete mode 100644 foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiService.kt delete mode 100644 foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiServiceBridge.kt delete mode 100644 foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayExtension.kt diff --git a/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/AbstractFoojayToolchainsPluginFunctionalTest.kt b/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/AbstractFoojayToolchainsPluginFunctionalTest.kt index db23290..41b197f 100644 --- a/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/AbstractFoojayToolchainsPluginFunctionalTest.kt +++ b/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/AbstractFoojayToolchainsPluginFunctionalTest.kt @@ -49,9 +49,8 @@ abstract class AbstractFoojayToolchainsPluginFunctionalTest { override fun filterRequest(originalRequest: HttpRequest): HttpFilters { return object : HttpFiltersAdapter(originalRequest) { override fun clientToProxyRequest(httpObject: HttpObject): HttpResponse? { - // Increment whenever the proxy intercepts a request frame + // Increment whenever the proxy intercepts a request if (httpObject is HttpRequest) { - System.err.println("Captured traffic in proxy!") proxyInterceptorCount.incrementAndGet() } return null // Continue normal routing diff --git a/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPluginFunctionalTest.kt b/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPluginFunctionalTest.kt index c59b369..0c0f79e 100644 --- a/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPluginFunctionalTest.kt +++ b/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPluginFunctionalTest.kt @@ -1,13 +1,12 @@ package org.gradle.toolchains.foojay -import org.gradle.internal.classpath.Instrumented.systemProperty import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource -import java.io.PrintWriter import kotlin.test.Test +import kotlin.test.assertEquals import kotlin.test.assertTrue -class FoojayToolchainsPluginFunctionalTest: AbstractFoojayToolchainsPluginFunctionalTest() { +class FoojayToolchainsPluginFunctionalTest : AbstractFoojayToolchainsPluginFunctionalTest() { @ParameterizedTest(name = "gradle version: {0}") @MethodSource("getGradleTestVersions") @@ -53,13 +52,6 @@ class FoojayToolchainsPluginFunctionalTest: AbstractFoojayToolchainsPluginFuncti id("org.gradle.toolchains.foojay-resolver") } - // This is the only syntax compatible with version 7.6 to current (9.8). - configure { - proxy { - autoDetect.set(true) - } - } - toolchainManagement { jvm { javaRepositories { @@ -96,6 +88,47 @@ class FoojayToolchainsPluginFunctionalTest: AbstractFoojayToolchainsPluginFuncti assertTrue(proxyInterceptorCount.get() > 0, "Traffic bypassed the proxy.") } + @ParameterizedTest(name = "gradle version: {0}") + @MethodSource("getGradleTestVersions") + fun `plugin can ignore proxy`(gradleVersion: String) { + val settings = """ + plugins { + id("org.gradle.toolchains.foojay-resolver") + } + + toolchainManagement { + jvm { + javaRepositories { + repository("foojay") { + resolverClass.set(org.gradle.toolchains.foojay.FoojayToolchainResolver::class.java) + } + } + } + } + """.trimIndent() + + val buildScript = """ + plugins { + java + } + + java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(${getDifferentJavaVersion()})) + } + } + """ + val arguments = listOf( + // To make sure Gradle does not pick up local JDK installations. + "-Porg.gradle.java.installations.auto-detect=false" + ) + val result = runner(settings, buildScript, arguments) + .withGradleVersion(gradleVersion) + .build() + assertProvisioningSuccessful(result) + assertEquals(proxyInterceptorCount.get(), 0, "Traffic passed through the proxy.") + } + @Test fun `generates useful error for unsupported Gradle versions`() { val settings = """ @@ -163,7 +196,9 @@ class FoojayToolchainsPluginFunctionalTest: AbstractFoojayToolchainsPluginFuncti .withGradleVersion(gradleVersion) .buildAndFail() - assertTrue("> Failed to apply plugin 'org.gradle.toolchains.foojay-resolver'.\n" + - " > Settings plugins must be applied in the settings script." in result.output) + assertTrue( + "> Failed to apply plugin 'org.gradle.toolchains.foojay-resolver'.\n" + + " > Settings plugins must be applied in the settings script." in result.output + ) } } diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt index 7d2ad03..6ee774a 100644 --- a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt +++ b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt @@ -8,6 +8,8 @@ import org.gradle.jvm.toolchain.JvmVendorSpec import org.gradle.platform.Architecture import org.gradle.platform.OperatingSystem import org.slf4j.LoggerFactory +import java.net.InetSocketAddress +import java.net.Proxy import java.net.ProxySelector import java.net.URI import java.net.URLEncoder @@ -29,36 +31,13 @@ private const val ENDPOINT_ROOT = "api.foojay.io/disco/v3.0" private const val DISTRIBUTIONS_ENDPOINT = "$ENDPOINT_ROOT/distributions" private const val PACKAGES_ENDPOINT = "$ENDPOINT_ROOT/packages" -class FoojayApiConfig { - val proxy = ProxyConfig() - class ProxyConfig { - var autoDetect: Boolean = false - } -} - @Suppress("UnstableApiUsage") -class FoojayApi( - private val configs: FoojayApiConfig -) { - private val logger = LoggerFactory.getLogger(FoojayApi::class.java) +class FoojayApi { + private val distributions = mutableListOf() private val httpClient = HttpClient.newBuilder() - .also { builder -> - // Only active the default ProxySelector when plugin configuration `detectProxy` is true - // to keep default plugin behavior. - // The default behavior is to ignore proxy configuration so that it won't introduce side effects if - // this plugin is run in an environment where proxy configurations are defined and that it is not - // expected that the project using this plugin uses the proxy. - if (configs.proxy.autoDetect) { - // Configures the system-wide proxy selector. - builder.proxy(ProxySelector.getDefault()) - } else { - //builder.proxy(HttpClient.Builder.NO_PROXY) - builder.proxy(ProxySelector.getDefault()) - } - builder.connectTimeout(CONNECT_TIMEOUT) - } + .connectTimeout(CONNECT_TIMEOUT) .build() @Suppress("LongParameterList") diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiService.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiService.kt deleted file mode 100644 index 214db5d..0000000 --- a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiService.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.gradle.toolchains.foojay - -import org.gradle.api.provider.Property -import org.gradle.api.services.BuildService -import org.gradle.api.services.BuildServiceParameters - -interface FoojayApiParameters : BuildServiceParameters { - val detectProxy: Property - - fun toConfigs(): FoojayApiConfig { - return FoojayApiConfig().apply { - proxy.autoDetect = detectProxy.get() - } - } -} - -abstract class FoojayApiService : BuildService { - val api = FoojayApi(parameters.toConfigs()) -} diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiServiceBridge.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiServiceBridge.kt deleted file mode 100644 index 0db381e..0000000 --- a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApiServiceBridge.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.gradle.toolchains.foojay - -import org.gradle.api.provider.Provider - - -object FoojayApiServiceBridge { - private var serviceProvider: Provider? = null - - fun init(serviceProvider: Provider) { - this.serviceProvider = serviceProvider - } - - fun getService(): FoojayApiService? { - return serviceProvider?.orNull - } -} \ No newline at end of file diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayExtension.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayExtension.kt deleted file mode 100644 index c40ce43..0000000 --- a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayExtension.kt +++ /dev/null @@ -1,24 +0,0 @@ -package org.gradle.toolchains.foojay - -import org.gradle.api.Action -import org.gradle.api.model.ObjectFactory -import org.gradle.api.provider.Property -import javax.inject.Inject - -@Suppress("UnusedPrivateProperty") -abstract class ProxyConfig @Inject constructor(objects: ObjectFactory) { - abstract val autoDetect: Property - - init { - autoDetect.convention(false) - } -} - -abstract class FoojayExtension @Inject constructor(objectFactory: ObjectFactory) { - - val proxy: ProxyConfig = objectFactory.newInstance(ProxyConfig::class.java) - - fun proxy(action: Action) { - action.execute(proxy) - } -} diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainResolver.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainResolver.kt index 5d903c2..84ff12c 100644 --- a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainResolver.kt +++ b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainResolver.kt @@ -11,8 +11,7 @@ import java.util.* @Suppress("UnstableApiUsage") abstract class FoojayToolchainResolver : JavaToolchainResolver { - private val apiService = FoojayApiServiceBridge.getService() - ?: throw RuntimeException("failed to retrieve FoojayApiService instance") + private val api = FoojayApi() override fun resolve(request: JavaToolchainRequest): Optional { val spec = request.javaToolchainSpec @@ -22,7 +21,7 @@ abstract class FoojayToolchainResolver : JavaToolchainResolver { false } val platform = request.buildPlatform - val links = apiService.api.toPackage( + val links = api.toPackage( spec.languageVersion.get(), spec.vendor.get(), spec.implementation.get(), diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPlugin.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPlugin.kt index 0e713dd..84301cc 100644 --- a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPlugin.kt +++ b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPlugin.kt @@ -4,14 +4,10 @@ package org.gradle.toolchains.foojay import org.gradle.api.initialization.Settings -import org.gradle.api.internal.SettingsInternal import org.gradle.jvm.toolchain.JavaToolchainResolverRegistry import org.gradle.kotlin.dsl.support.serviceOf import org.gradle.util.GradleVersion -private const val FOOJAY_EXTENSION_NAME = "foojay" -private const val FOOJAY_API_SERVICE_NAME = "foojayApi" - @Suppress("unused", "UnstableApiUsage") abstract class FoojayToolchainsPlugin: AbstractFoojayToolchainPlugin() { @@ -20,14 +16,6 @@ abstract class FoojayToolchainsPlugin: AbstractFoojayToolchainPlugin() { if (GradleVersion.current().baseVersion < GradleVersion.version("7.6")) { throw RuntimeException("${FoojayToolchainsPlugin::class.simpleName} needs Gradle version 7.6 or higher") } - val extension = settings.extensions.create(FOOJAY_EXTENSION_NAME, FoojayExtension::class.java) - val service = settings.gradle.sharedServices.registerIfAbsent( - FOOJAY_API_SERVICE_NAME, - FoojayApiService::class.java - ) { - this.parameters.detectProxy.set(extension.proxy.autoDetect) - } - FoojayApiServiceBridge.init(service) settings.plugins.apply("jvm-toolchain-management") settings.serviceOf() .apply { register(FoojayToolchainResolver::class.java) } From cda37534e6cfe2759a43ba0a7be2bba3ad339c8b Mon Sep 17 00:00:00 2001 From: RB1248 Date: Fri, 17 Jul 2026 00:40:55 -0400 Subject: [PATCH 3/6] removed test code and fixed FoojayApi call in tests --- foojay-resolver/build.gradle.kts | 5 ----- .../kotlin/org/gradle/toolchains/foojay/FoojayApiTest.kt | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/foojay-resolver/build.gradle.kts b/foojay-resolver/build.gradle.kts index 9435139..ad4d769 100644 --- a/foojay-resolver/build.gradle.kts +++ b/foojay-resolver/build.gradle.kts @@ -102,11 +102,6 @@ signing { testing { suites { val functionalTest by registering(JvmTestSuite::class) { - targets.all { - testTask.configure { - testLogging.showStandardStreams = true - } - } dependencies { implementation("org.jetbrains.kotlin:kotlin-test-junit5") implementation(libs.littleproxy) diff --git a/foojay-resolver/src/test/kotlin/org/gradle/toolchains/foojay/FoojayApiTest.kt b/foojay-resolver/src/test/kotlin/org/gradle/toolchains/foojay/FoojayApiTest.kt index 7767558..9ac4c77 100644 --- a/foojay-resolver/src/test/kotlin/org/gradle/toolchains/foojay/FoojayApiTest.kt +++ b/foojay-resolver/src/test/kotlin/org/gradle/toolchains/foojay/FoojayApiTest.kt @@ -21,7 +21,7 @@ import kotlin.test.assertTrue @Suppress("UnstableApiUsage") class FoojayApiTest { - private val api = FoojayApi(FoojayApiConfig()) + private val api = FoojayApi() @ParameterizedTest(name = "javaVersion: {0}, vendor: {1}, isJ9: {2}, os: {3}, arch: {4}") @MethodSource("getData") From 28002aabd273a9cb53facf946212ac2232dc6bc6 Mon Sep 17 00:00:00 2001 From: RB1248 Date: Fri, 17 Jul 2026 00:43:20 -0400 Subject: [PATCH 4/6] removed unused imports --- .../main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt index 6ee774a..85b0d74 100644 --- a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt +++ b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt @@ -1,16 +1,11 @@ package org.gradle.toolchains.foojay import org.gradle.api.GradleException -import org.gradle.api.logging.Logger import org.gradle.jvm.toolchain.JavaLanguageVersion import org.gradle.jvm.toolchain.JvmImplementation import org.gradle.jvm.toolchain.JvmVendorSpec import org.gradle.platform.Architecture import org.gradle.platform.OperatingSystem -import org.slf4j.LoggerFactory -import java.net.InetSocketAddress -import java.net.Proxy -import java.net.ProxySelector import java.net.URI import java.net.URLEncoder import java.net.http.HttpClient @@ -18,7 +13,6 @@ import java.net.http.HttpRequest import java.net.http.HttpResponse import java.nio.charset.StandardCharsets.UTF_8 import java.time.Duration -import kotlin.jvm.java @Suppress("MagicNumber") private val CONNECT_TIMEOUT = Duration.ofSeconds(10) From dabeb08f0787b96a8c5d114a827a271f81aaa1a1 Mon Sep 17 00:00:00 2001 From: RB1248 Date: Fri, 17 Jul 2026 00:46:09 -0400 Subject: [PATCH 5/6] removed unecessary test --- .../FoojayToolchainsPluginFunctionalTest.kt | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPluginFunctionalTest.kt b/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPluginFunctionalTest.kt index 0c0f79e..a91d645 100644 --- a/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPluginFunctionalTest.kt +++ b/foojay-resolver/src/functionalTest/kotlin/org/gradle/toolchains/foojay/FoojayToolchainsPluginFunctionalTest.kt @@ -88,47 +88,6 @@ class FoojayToolchainsPluginFunctionalTest : AbstractFoojayToolchainsPluginFunct assertTrue(proxyInterceptorCount.get() > 0, "Traffic bypassed the proxy.") } - @ParameterizedTest(name = "gradle version: {0}") - @MethodSource("getGradleTestVersions") - fun `plugin can ignore proxy`(gradleVersion: String) { - val settings = """ - plugins { - id("org.gradle.toolchains.foojay-resolver") - } - - toolchainManagement { - jvm { - javaRepositories { - repository("foojay") { - resolverClass.set(org.gradle.toolchains.foojay.FoojayToolchainResolver::class.java) - } - } - } - } - """.trimIndent() - - val buildScript = """ - plugins { - java - } - - java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(${getDifferentJavaVersion()})) - } - } - """ - val arguments = listOf( - // To make sure Gradle does not pick up local JDK installations. - "-Porg.gradle.java.installations.auto-detect=false" - ) - val result = runner(settings, buildScript, arguments) - .withGradleVersion(gradleVersion) - .build() - assertProvisioningSuccessful(result) - assertEquals(proxyInterceptorCount.get(), 0, "Traffic passed through the proxy.") - } - @Test fun `generates useful error for unsupported Gradle versions`() { val settings = """ From 2bd0b9cd32c8ecc4acde6126675cf251b855fb84 Mon Sep 17 00:00:00 2001 From: RB1248 Date: Fri, 17 Jul 2026 00:50:49 -0400 Subject: [PATCH 6/6] removed test log --- .../src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt index 85b0d74..53a5bb6 100644 --- a/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt +++ b/foojay-resolver/src/main/kotlin/org/gradle/toolchains/foojay/FoojayApi.kt @@ -90,7 +90,6 @@ class FoojayApi { params: Map ): String { val uri = URI.create("$SCHEMA://$endpoint?${toParameterString(params)}") - System.err.println("👉 Making http request to: $uri") val request = HttpRequest.newBuilder() .uri(uri) .header("Content-Type", "application/json")