From 5caaccd6d618c5dd61d0931f55841d90132aaf9d Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Tue, 12 Aug 2025 14:41:20 +0200 Subject: [PATCH 1/8] Introduce dedicated toolchain resolver for EA java versions --- .../internal/info/GlobalBuildInfoPlugin.java | 26 ++- ...arlyAccessCatalogJdkToolchainResolver.java | 201 ++++++++++++++++++ .../JavaToolChainResolverPlugin.java | 1 + .../OracleOpenJdkToolchainResolver.java | 13 +- .../AbstractToolchainResolverSpec.groovy | 1 + .../AdoptiumJdkToolchainResolverSpec.groovy | 2 +- ...cessCatalogJdkToolchainResolverSpec.groovy | 68 ++++++ settings.gradle | 4 + 8 files changed, 302 insertions(+), 14 deletions(-) create mode 100644 build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolver.java create mode 100644 build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolverSpec.groovy diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java index 675f1198b2a7d..404d61a03f1c7 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java @@ -40,6 +40,7 @@ import org.gradle.jvm.toolchain.JavaToolchainService; import org.gradle.jvm.toolchain.JavaToolchainSpec; import org.gradle.jvm.toolchain.JvmVendorSpec; +import org.gradle.jvm.toolchain.internal.DefaultJvmVendorSpec; import org.gradle.jvm.toolchain.internal.InstallationLocation; import org.gradle.util.GradleVersion; import org.jetbrains.annotations.NotNull; @@ -63,6 +64,7 @@ import javax.inject.Inject; import static org.elasticsearch.gradle.internal.conventions.GUtils.elvis; +import static org.elasticsearch.gradle.internal.toolchain.EarlyAccessCatalogJdkToolchainResolver.findLatestEABuildNumber; public class GlobalBuildInfoPlugin implements Plugin { private static final Logger LOGGER = Logging.getLogger(GlobalBuildInfoPlugin.class); @@ -338,6 +340,7 @@ private Provider findRuntimeJavaHome() { String runtimeJavaProperty = System.getProperty("runtime.java"); if (runtimeJavaProperty != null) { + System.out.println("GlobalBuildInfoPlugin.findRuntimeJavaHome"); return resolveJavaHomeFromToolChainService(runtimeJavaProperty); } if (System.getenv("RUNTIME_JAVA_HOME") != null) { @@ -355,9 +358,26 @@ private Provider findRuntimeJavaHome() { @NotNull private Provider resolveJavaHomeFromToolChainService(String version) { - Property value = objectFactory.property(JavaLanguageVersion.class).value(JavaLanguageVersion.of(version)); - return toolChainService.launcherFor(javaToolchainSpec -> javaToolchainSpec.getLanguageVersion().value(value)) - .map(launcher -> launcher.getMetadata().getInstallationPath().getAsFile()); + JavaLanguageVersion languageVersion = JavaLanguageVersion.of(version); + Property value = objectFactory.property(JavaLanguageVersion.class).value(languageVersion); + return toolChainService.launcherFor(javaToolchainSpec -> { + javaToolchainSpec.getLanguageVersion().value(value); + + if (Integer.parseInt(VersionProperties.getBundledJdkMajorVersion()) < Integer.parseInt(version)) { + // If the requested version is higher than the bundled JDK, we need trick the toolchain into using our early access catalog + // Otherwise, we use the default implementation + Integer buildNumber = Integer.getInteger("runtime.java.build"); + + if (buildNumber == null) { + buildNumber = Integer.getInteger("runtime.java." + version + ".build"); + } + if (buildNumber == null) { + buildNumber = findLatestEABuildNumber(languageVersion); + } + javaToolchainSpec.getVendor() + .set(DefaultJvmVendorSpec.of("Oracle[" + languageVersion + "/" + buildNumber + "]")); + } + }).map(launcher -> launcher.getMetadata().getInstallationPath().getAsFile()); } public static String getResourceContents(String resourcePath) { diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolver.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolver.java new file mode 100644 index 0000000000000..4bea812b2adc3 --- /dev/null +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolver.java @@ -0,0 +1,201 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.gradle.internal.toolchain; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; + +import org.elasticsearch.gradle.VersionProperties; +import org.gradle.jvm.toolchain.JavaLanguageVersion; +import org.gradle.jvm.toolchain.JavaToolchainDownload; +import org.gradle.jvm.toolchain.JavaToolchainRequest; +import org.gradle.jvm.toolchain.JavaToolchainSpec; +import org.gradle.jvm.toolchain.JvmVendorSpec; +import org.gradle.jvm.toolchain.internal.DefaultJvmVendorSpec; +import org.gradle.platform.Architecture; +import org.gradle.platform.BuildPlatform; +import org.gradle.platform.OperatingSystem; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public abstract class EarlyAccessCatalogJdkToolchainResolver extends AbstractCustomJavaToolchainResolver { + + interface JdkBuild { + JavaLanguageVersion languageVersion(); + + String url(String os, String arch, String extension); + } + + private static final Pattern PATTERN = Pattern.compile("Oracle\\[(\\d+)/(\\d+)\\]"); + + public static class EaCatalogVendorSpec extends JvmVendorSpec { + + private final JavaLanguageVersion languageVersion; + private final int buildNumber; + + private EaCatalogVendorSpec(JavaLanguageVersion languageVersion, int buildNumber) { + this.languageVersion = languageVersion; + this.buildNumber = buildNumber; + } + + public static EaCatalogVendorSpec of(JavaLanguageVersion languageVersion, int buildNumber) { + return new EaCatalogVendorSpec(languageVersion, buildNumber); + } + + @Override + public boolean matches(String vendor) { + return false; + } + + public int getBuildNumber() { + return buildNumber; + } + } + + @FunctionalInterface + interface EarlyAccessJdkBuildResolver { + Optional findLatestEABuild(JavaLanguageVersion languageVersion); + } + + // allow overriding for testing + EarlyAccessJdkBuildResolver earlyAccessJdkBuildResolver = (languageVersion) -> findLatestEABuild(languageVersion); + + record EarlyAccessJdkBuild(JavaLanguageVersion languageVersion, int buildNumber) implements JdkBuild { + @Override + public String url(String os, String arch, String extension) { + // example: + // https://builds.es-jdk-archive.com/jdks/openjdk/26/openjdk-26-ea+6/openjdk-26-ea+6_linux-aarch64_bin.tar.gz + return "https://builds.es-jdk-archive.com/jdks/openjdk/" + + languageVersion.asInt() + + "/" + + "openjdk-" + + languageVersion.asInt() + + "-ea+" + + buildNumber + + "/" + + "openjdk-" + + languageVersion.asInt() + + "-ea+" + + buildNumber + + "_" + + os + + "-" + + arch + + "_bin." + + extension; + } + } + + private static final List supportedOperatingSystems = List.of( + OperatingSystem.MAC_OS, + OperatingSystem.LINUX, + OperatingSystem.WINDOWS + ); + + // static EarlyAccessJdkBuild getEarlyAccessBuild(JavaLanguageVersion languageVersion, String buildNumber) { + // // first try the unversioned override, then the versioned override which has higher precedence + // buildNumber = System.getProperty("runtime.java.build", buildNumber); + // buildNumber = System.getProperty("runtime.java." + languageVersion.asInt() + ".build", buildNumber); + // + // return new EarlyAccessJdkBuild(languageVersion, buildNumber); + // } + + /** + * We need some place to map JavaLanguageVersion to buildNumber, minor version etc. + * */ + @Override + public Optional resolve(JavaToolchainRequest request) { + if (Integer.parseInt(VersionProperties.getBundledJdkMajorVersion()) >= request.getJavaToolchainSpec() + .getLanguageVersion() + .get() + .asInt()) { + // This resolver only handles early access builds, that are beyond the last bundled jdk version + } + return findSupportedBuild(request).map(build -> { + OperatingSystem operatingSystem = request.getBuildPlatform().getOperatingSystem(); + String extension = operatingSystem.equals(OperatingSystem.WINDOWS) ? "zip" : "tar.gz"; + String arch = toArchString(request.getBuildPlatform().getArchitecture()); + String os = toOsString(operatingSystem); + return (JavaToolchainDownload) () -> URI.create(build.url(os, arch, extension)); + }); + } + + /** + * Check if request can be full-filled by this resolver: + * 1. Aarch64 windows images are not supported + */ + private Optional findSupportedBuild(JavaToolchainRequest request) { + JavaToolchainSpec javaToolchainSpec = request.getJavaToolchainSpec(); + BuildPlatform buildPlatform = request.getBuildPlatform(); + Architecture architecture = buildPlatform.getArchitecture(); + OperatingSystem operatingSystem = buildPlatform.getOperatingSystem(); + + if (supportedOperatingSystems.contains(operatingSystem) == false + || Architecture.AARCH64 == architecture && OperatingSystem.WINDOWS == operatingSystem) { + return Optional.empty(); + } + + JavaLanguageVersion languageVersion = javaToolchainSpec.getLanguageVersion().get(); + // resolve from vendor spec if available + if (javaToolchainSpec.getVendor().isPresent() && javaToolchainSpec.getVendor().get() instanceof DefaultJvmVendorSpec) { + DefaultJvmVendorSpec spec = (DefaultJvmVendorSpec) javaToolchainSpec.getVendor().get(); + String criteria = spec.toCriteria(); + Matcher matcher = PATTERN.matcher(criteria); + if (matcher.matches()) { + int level = Integer.parseInt(matcher.group(1)); + int build = Integer.parseInt(matcher.group(2)); + assert level == languageVersion.asInt() : "Language version does not match: " + level + " != " + languageVersion.asInt(); + return Optional.of(new EarlyAccessJdkBuild(languageVersion, build)); + } + } + return findLatestEABuild(languageVersion); + } + + private static Optional findLatestEABuild(JavaLanguageVersion languageVersion) { + System.out.println("CatalogJdkToolchainResolver.findLatestEABuild"); + try { + URL url = new URL("https://storage.googleapis.com/elasticsearch-jdk-archive/jdks/openjdk/latest.json"); + try (InputStream is = url.openStream()) { + ObjectMapper mapper = new ObjectMapper(); + JsonNode node = mapper.readTree(is); + ArrayNode buildsNode = (ArrayNode) node.get("builds"); + List buildsList = new ArrayList<>(); + buildsNode.forEach(buildsList::add); + List eaBuilds = buildsList.stream() + .map( + n -> new EarlyAccessJdkBuild( + JavaLanguageVersion.of(n.get("major").asText()), + Integer.parseInt(n.get("build").asText()) + ) + ) + .toList(); + return eaBuilds.stream().filter(ea -> ea.languageVersion().equals(languageVersion)).findFirst(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } catch (MalformedURLException e) { + return Optional.empty(); + } + } + + public static int findLatestEABuildNumber(JavaLanguageVersion languageVersion) { + return findLatestEABuild(languageVersion).map(ea -> ea.buildNumber()).get(); + } +} diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/JavaToolChainResolverPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/JavaToolChainResolverPlugin.java index b89eb87325754..1cacbb38fdd5d 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/JavaToolChainResolverPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/JavaToolChainResolverPlugin.java @@ -23,6 +23,7 @@ public void apply(Settings settings) { settings.getPlugins().apply("jvm-toolchain-management"); JavaToolchainResolverRegistry registry = getToolchainResolverRegistry(); registry.register(OracleOpenJdkToolchainResolver.class); + registry.register(EarlyAccessCatalogJdkToolchainResolver.class); registry.register(AdoptiumJdkToolchainResolver.class); registry.register(ArchivedOracleJdkToolchainResolver.class); } diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolver.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolver.java index dbf60e1b4f4d8..40d8178fcbd88 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolver.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolver.java @@ -61,17 +61,11 @@ public String url(String os, String arch, String extension) { record EarlyAccessJdkBuild(JavaLanguageVersion languageVersion, String buildNumber) implements JdkBuild { @Override public String url(String os, String arch, String extension) { - // example: - // https://builds.es-jdk-archive.com/jdks/openjdk/26/openjdk-26-ea+6/openjdk-26-ea+6_linux-aarch64_bin.tar.gz - return "https://builds.es-jdk-archive.com/jdks/openjdk/" + return "https://download.java.net/java/early_access/jdk" + languageVersion.asInt() + "/" - + "openjdk-" - + languageVersion.asInt() - + "-ea+" + buildNumber - + "/" - + "openjdk-" + + "/GPL/openjdk-" + languageVersion.asInt() + "-ea+" + buildNumber @@ -96,8 +90,7 @@ public String url(String os, String arch, String extension) { // package private so it can be replaced by tests List builds = List.of( - getBundledJdkBuild(VersionProperties.getBundledJdkVersion(), VersionProperties.getBundledJdkMajorVersion()), - getEarlyAccessBuild(JavaLanguageVersion.of(25), "3") + getBundledJdkBuild(VersionProperties.getBundledJdkVersion(), VersionProperties.getBundledJdkMajorVersion()) ); static EarlyAccessJdkBuild getEarlyAccessBuild(JavaLanguageVersion languageVersion, String buildNumber) { diff --git a/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/AbstractToolchainResolverSpec.groovy b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/AbstractToolchainResolverSpec.groovy index cea96437129a6..05372f25a4981 100644 --- a/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/AbstractToolchainResolverSpec.groovy +++ b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/AbstractToolchainResolverSpec.groovy @@ -73,6 +73,7 @@ abstract class AbstractToolchainResolverSpec extends Specification { _ * languageVersionProperty.get() >> languageVersion Property vendorSpecProperty = Mock() + _ * vendorSpecProperty.isPresent() >> true _ * vendorSpecProperty.get() >> vendorSpec _ * toolchainSpec.getVendor() >> vendorSpecProperty diff --git a/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolverSpec.groovy b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolverSpec.groovy index 5abb78b062c39..f26c9c46d52b3 100644 --- a/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolverSpec.groovy +++ b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolverSpec.groovy @@ -47,7 +47,7 @@ class AdoptiumJdkToolchainResolverSpec extends AbstractToolchainResolverSpec { @Override def supportedRequests() { return [ - [19, ADOPTIUM, MAC_OS, X86_64, "https://api.adoptium.net/v3/binary/version/jdk-19.1.1.1+37.1/mac/x64/jdk/hotspot/normal/eclipse?project=jdk"], + [19, ADOPTIUM, LINUX, X86_64, "https://api.adoptium.net/v3/binary/version/jdk-19.1.1.1+37.1/linux/x64/jdk/hotspot/normal/eclipse?project=jdk"], [19, ADOPTIUM, WINDOWS, X86_64, "https://api.adoptium.net/v3/binary/version/jdk-19.1.1.1+37.1/windows/x64/jdk/hotspot/normal/eclipse?project=jdk"], [19, ADOPTIUM, MAC_OS, AARCH64, "https://api.adoptium.net/v3/binary/version/jdk-19.1.1.1+37.1/mac/aarch64/jdk/hotspot/normal/eclipse?project=jdk"], diff --git a/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolverSpec.groovy b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolverSpec.groovy new file mode 100644 index 0000000000000..295abc9c6d968 --- /dev/null +++ b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolverSpec.groovy @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.gradle.internal.toolchain + +import org.gradle.api.services.BuildServiceParameters +import org.gradle.jvm.toolchain.JavaLanguageVersion +import org.gradle.jvm.toolchain.JavaToolchainResolver +import org.gradle.jvm.toolchain.JvmVendorSpec + +import static org.gradle.platform.Architecture.AARCH64 +import static org.gradle.platform.Architecture.X86_64 +import static org.gradle.platform.OperatingSystem.* + +class EarlyAccessCatalogJdkToolchainResolverSpec extends AbstractToolchainResolverSpec { + @Override + JavaToolchainResolver resolverImplementation() { + def resolver = new EarlyAccessCatalogJdkToolchainResolver() { + @Override + BuildServiceParameters.None getParameters() { + return null + } + } + resolver.earlyAccessJdkBuildResolver = () -> { + return Optional.of( + new EarlyAccessCatalogJdkToolchainResolver.EarlyAccessJdkBuild(JavaLanguageVersion.of(25), 31), + new EarlyAccessCatalogJdkToolchainResolver.EarlyAccessJdkBuild(JavaLanguageVersion.of(26), 6) + ) + } + return resolver + } + + def anyVendorMatch() { + return JvmVendorSpec.ANY + } + @Override + def supportedRequests() { + return [ + [25, vSpec( + 25, + 30 + ), LINUX, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+30/openjdk-25-ea+30_linux-x64_bin.tar.gz"], + [26, vSpec( + 26, + 6 + ), WINDOWS, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/26/openjdk-26-ea+6/openjdk-26-ea+6_windows-x64_bin.zip"], + [26, vSpec( + 26, + 6 + ), MAC_OS, AARCH64, "https://builds.es-jdk-archive.com/jdks/openjdk/26/openjdk-26-ea+6/openjdk-26-ea+6_macos-aarch64_bin.tar.gz"] + ] + } + + private JvmVendorSpec vSpec(int version, int build) { + return org.gradle.jvm.toolchain.internal.DefaultJvmVendorSpec.of("EarlyAccessJvmCatalog[" + version + "/" + build + "]"); + } + + @Override + def unsupportedRequests() { + return [] + } +} diff --git a/settings.gradle b/settings.gradle index e8cd2a3b5d826..36ef9809e0152 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,7 @@ import org.elasticsearch.gradle.internal.toolchain.OracleOpenJdkToolchainResolver import org.elasticsearch.gradle.internal.toolchain.ArchivedOracleJdkToolchainResolver import org.elasticsearch.gradle.internal.toolchain.AdoptiumJdkToolchainResolver +import org.elasticsearch.gradle.internal.toolchain.EarlyAccessCatalogJdkToolchainResolver pluginManagement { repositories { @@ -42,6 +43,9 @@ toolchainManagement { repository('archivedOracleJdks') { resolverClass = ArchivedOracleJdkToolchainResolver } + repository('EarlyAccessCatalogJdks') { + resolverClass = EarlyAccessCatalogJdkToolchainResolver + } } } } From 48476dd40bc66561ccb2f48018d5ae5a8a00ca4d Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Wed, 13 Aug 2025 17:43:21 +0200 Subject: [PATCH 2/8] Fix reproducability of builds against Java EA versions This fixes a reproducability issue when using the gradle javaToolChain api. There is no way to test toolchain candidates reliable against the build number in use. This meant that ones you e.g. have resolved some version of java 25, gradle toolchain detection does not detect the difference between certain builds (or even ea vs. released version) Therefore we fallback to rely on our custom JDKDownloadPlugin for now here. Syncing with the gradle team, they want to fix this somewhen in 9.x. We will revisit our solution ones something is available. Ultimately we want to get rid of usages of the JDK download plugin. --- BUILDING.md | 25 ++++++- .../AbstractGitAwareGradleFuncTest.groovy | 1 - .../internal/JdkDownloadPluginFuncTest.groovy | 56 +++++++++------ .../elasticsearch/gradle/internal/Jdk.java | 17 ++++- .../gradle/internal/JdkDownloadPlugin.java | 13 ++++ .../internal/info/GlobalBuildInfoPlugin.java | 67 ++++++++++------- ...arlyAccessCatalogJdkToolchainResolver.java | 71 ++++--------------- .../OracleOpenJdkToolchainResolver.java | 28 -------- .../gradle/internal/JdkSpec.groovy | 46 ++++++++++++ ...cessCatalogJdkToolchainResolverSpec.groovy | 40 +++++------ .../OracleOpenJdkToolchainResolverSpec.groovy | 51 +------------ .../elasticsearch/gradle/Architecture.java | 8 ++- .../gradle/DistributionDownloadPlugin.java | 10 +-- .../java/org/elasticsearch/gradle/OS.java | 13 +++- build.gradle | 4 +- gradle/verification-metadata.xml | 2 + settings.gradle | 3 - test/immutable-collections-patch/build.gradle | 4 -- 18 files changed, 232 insertions(+), 227 deletions(-) create mode 100644 build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/JdkSpec.groovy diff --git a/BUILDING.md b/BUILDING.md index 0dc368140de67..a71622687738f 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -92,7 +92,7 @@ uses the changed dependencies. In most cases, `precommit` or `check` are good ca We prefer sha256 checksums as md5 and sha1 are not considered safe anymore these days. The generated entry will have the `origin` attribute been set to `Generated by Gradle`. -> [!Tip] +> [!Tip] > A manual confirmation of the Gradle generated checksums is currently not mandatory. > If you want to add a level of verification you can manually confirm the checksum (e.g. by looking it up on the website of the library) > Please replace the content of the `origin` attribute by `official site` in that case. @@ -186,6 +186,25 @@ dependencies { To test an unreleased development version of a third party dependency you have several options. +### How do I test against java early access (ea) versions? + +Currently only openjdk EA builds by oracle are supported. +To test against an early access version java version you can pass the major java version +to test against via system property (e.g. -Druntime.java=26): + +``` +./gradlew clean test -Druntime.java=26 +``` + +This will run the tests using the JDK 26 EA version and pick the latest available build of the matching JDK EA version we expose +in our custom jdk catalogue at `https://storage.googleapis.com/elasticsearch-jdk-archive/jdks/openjdk/latest.json`. + +To run against a specific build number of the EA build you can pass a second system property (e.g. `-Druntime.java.build=6`): + +``` +./gradlew clean test -Druntime.java=26 -Druntime.java.build=6 +``` + #### How to use a Maven based third party dependency via `mavenlocal`? 1. Clone the third party repository locally @@ -229,7 +248,7 @@ In addition to snapshot builds JitPack supports building Pull Requests. Simply u 3. Run the Gradle build as needed. Keep in mind the initial resolution might take a bit longer as this needs to be built by JitPack in the background before we can resolve the adhoc built dependency. -> [!Note] +> [!Note] > You should only use that approach locally or on a developer branch for production dependencies as we do not want to ship unreleased libraries into our releases. @@ -261,7 +280,7 @@ allprojects { ``` 4. Run the Gradle build as needed with `--write-verification-metadata` to ensure the Gradle dependency verification does not fail on your custom dependency. -> [!Note] +> [!Note] > As Gradle prefers to use modules whose descriptor has been created from real meta-data rather than being generated, flat directory repositories cannot be used to override artifacts with real meta-data from other repositories declared in the build. > For example, if Gradle finds only `jmxri-1.2.1.jar` in a flat directory repository, but `jmxri-1.2.1.pom` in another repository diff --git a/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/fixtures/AbstractGitAwareGradleFuncTest.groovy b/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/fixtures/AbstractGitAwareGradleFuncTest.groovy index f7c05894d3e95..d8cb55fc0373f 100644 --- a/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/fixtures/AbstractGitAwareGradleFuncTest.groovy +++ b/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/fixtures/AbstractGitAwareGradleFuncTest.groovy @@ -10,7 +10,6 @@ package org.elasticsearch.gradle.fixtures import org.apache.commons.io.FileUtils -import org.elasticsearch.gradle.internal.test.InternalAwareGradleRunner import org.gradle.testkit.runner.GradleRunner import org.junit.Rule import org.junit.rules.TemporaryFolder diff --git a/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/JdkDownloadPluginFuncTest.groovy b/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/JdkDownloadPluginFuncTest.groovy index a4635a7232754..b9c0196530dfd 100644 --- a/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/JdkDownloadPluginFuncTest.groovy +++ b/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/JdkDownloadPluginFuncTest.groovy @@ -33,13 +33,18 @@ class JdkDownloadPluginFuncTest extends AbstractGradleFuncTest { private static final String ADOPT_JDK_VERSION_15 = "15.0.2+7" private static final String AZUL_JDK_VERSION_8 = "8u302+b08" private static final String AZUL_8_DISTRO_VERSION = "8.56.0.23" + private static final String CATALOG_EA_VERSION = "25-ea+30" private static final String OPEN_JDK_VERSION = "12.0.1+99@123456789123456789123456789abcde" private static final Pattern JDK_HOME_LOGLINE = Pattern.compile("JDK HOME: (.*)") + def setup() { + configurationCacheCompatible = false // JDK class references configurations which break configuration cache + } + @Unroll - def "jdk #jdkVendor for #platform#suffix are downloaded and extracted"() { + def "jdk #distributionVersion #jdkVendor for #platform#suffix are downloaded and extracted"() { given: - def mockRepoUrl = urlPath(jdkVendor, jdkVersion, platform, arch); + def mockRepoUrl = urlPath(jdkVendor, jdkVersion, platform, arch, distributionVersion); def mockedContent = filebytes(jdkVendor, platform) buildFile.text = """ plugins { @@ -77,21 +82,26 @@ class JdkDownloadPluginFuncTest extends AbstractGradleFuncTest { where: platform | arch | jdkVendor | jdkVersion | distributionVersion | expectedJavaBin | suffix - "linux" | "x64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION | null | "bin/java" | "" - "linux" | "x64" | VENDOR_OPENJDK | OPEN_JDK_VERSION | null | "bin/java" | "" - "linux" | "x64" | VENDOR_OPENJDK | OPENJDK_VERSION_OLD | null | "bin/java" | "(old version)" - "windows" | "x64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION | null | "bin/java" | "" - "windows" | "x64" | VENDOR_OPENJDK | OPEN_JDK_VERSION | null | "bin/java" | "" - "windows" | "x64" | VENDOR_OPENJDK | OPENJDK_VERSION_OLD | null | "bin/java" | "(old version)" - "darwin" | "x64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION | null | "Contents/Home/bin/java" | "" - "darwin" | "x64" | VENDOR_OPENJDK | OPEN_JDK_VERSION | null | "Contents/Home/bin/java" | "" - "darwin" | "x64" | VENDOR_OPENJDK | OPENJDK_VERSION_OLD | null | "Contents/Home/bin/java" | "(old version)" - "mac" | "x64" | VENDOR_OPENJDK | OPEN_JDK_VERSION | null | "Contents/Home/bin/java" | "" - "mac" | "x64" | VENDOR_OPENJDK | OPENJDK_VERSION_OLD | null | "Contents/Home/bin/java" | "(old version)" - "darwin" | "aarch64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION | null | "Contents/Home/bin/java" | "" - "linux" | "aarch64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION | null | "bin/java" | "" - "linux" | "aarch64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION_11 | null | "bin/java" | "(jdk 11)" - "linux" | "aarch64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION_15 | null | "bin/java" | "(jdk 15)" + "linux" | "aarch64" | VENDOR_OPENJDK | CATALOG_EA_VERSION | "ea" | "bin/java" | "" + "linux" | "x64" | VENDOR_OPENJDK | CATALOG_EA_VERSION | "ea" | "bin/java" | "" + "darwin" | "aarch64" | VENDOR_OPENJDK | CATALOG_EA_VERSION | "ea" | "Contents/Home/bin/java" | "" + "darwin" | "x64" | VENDOR_OPENJDK | CATALOG_EA_VERSION | "ea" | "Contents/Home/bin/java" | "" + "windows" | "x64" | VENDOR_OPENJDK | CATALOG_EA_VERSION | "ea" | "bin/java" | "" + "linux" | "x64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION | "" | "bin/java" | "" + "linux" | "x64" | VENDOR_OPENJDK | OPEN_JDK_VERSION | "" | "bin/java" | "" + "linux" | "x64" | VENDOR_OPENJDK | OPENJDK_VERSION_OLD | "" | "bin/java" | "(old version)" + "windows" | "x64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION | "" | "bin/java" | "" + "windows" | "x64" | VENDOR_OPENJDK | OPEN_JDK_VERSION | "" | "bin/java" | "" + "windows" | "x64" | VENDOR_OPENJDK | OPENJDK_VERSION_OLD | "" | "bin/java" | "(old version)" + "darwin" | "x64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION | "" | "Contents/Home/bin/java" | "" + "darwin" | "x64" | VENDOR_OPENJDK | OPEN_JDK_VERSION | "" | "Contents/Home/bin/java" | "" + "darwin" | "x64" | VENDOR_OPENJDK | OPENJDK_VERSION_OLD | "" | "Contents/Home/bin/java" | "(old version)" + "mac" | "x64" | VENDOR_OPENJDK | OPEN_JDK_VERSION | "" | "Contents/Home/bin/java" | "" + "mac" | "x64" | VENDOR_OPENJDK | OPENJDK_VERSION_OLD | "" | "Contents/Home/bin/java" | "(old version)" + "darwin" | "aarch64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION | "" | "Contents/Home/bin/java" | "" + "linux" | "aarch64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION | "" | "bin/java" | "" + "linux" | "aarch64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION_11 | "" | "bin/java" | "(jdk 11)" + "linux" | "aarch64" | VENDOR_ADOPTIUM | ADOPT_JDK_VERSION_15 | "" | "bin/java" | "(jdk 15)" "darwin" | "aarch64" | VENDOR_ZULU | AZUL_JDK_VERSION_8 | AZUL_8_DISTRO_VERSION | "Contents/Home/bin/java" | "(jdk 8)" } @@ -214,13 +224,19 @@ class JdkDownloadPluginFuncTest extends AbstractGradleFuncTest { private static String urlPath(final String vendor, final String version, final String platform, - final String arch = 'x64') { - if (vendor.equals(VENDOR_ADOPTIUM)) { + final String arch = 'x64', + final String distributedVersion = '') { + final boolean isOld = version.equals(OPENJDK_VERSION_OLD); + + if (distributedVersion.equals("ea")) { + def effectivePlatform = isMac(platform) ? "macos" : platform; + def fileExtension = platform.toLowerCase().equals("windows") ? "zip" : "tar.gz"; + return "/jdks/openjdk/25/openjdk-${version}/openjdk-${version}_$effectivePlatform-${arch}_bin.$fileExtension"; + } else if (vendor.equals(VENDOR_ADOPTIUM)) { final String module = isMac(platform) ? "mac" : platform; return "/jdk-" + version + "/" + module + "/${arch}/jdk/hotspot/normal/adoptium"; } else if (vendor.equals(VENDOR_OPENJDK)) { final String effectivePlatform = isMac(platform) ? "macos" : platform; - final boolean isOld = version.equals(OPENJDK_VERSION_OLD); final String versionPath = isOld ? "jdk1/99" : "jdk12.0.1/123456789123456789123456789abcde/99"; final String filename = "openjdk-" + (isOld ? "1" : "12.0.1") + "_" + effectivePlatform + "-x64_bin." + extension(platform); return "/java/GA/" + versionPath + "/GPL/" + filename; diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/Jdk.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/Jdk.java index 4396a18c205c1..60d034ca4da74 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/Jdk.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/Jdk.java @@ -32,6 +32,7 @@ public class Jdk implements Buildable, Iterable { "(\\d+)(\\.\\d+\\.\\d+(?:\\.\\d+)?)?\\+(\\d+(?:\\.\\d+)?)(@([a-f0-9]{32}))?" ); private static final Pattern LEGACY_VERSION_PATTERN = Pattern.compile("(\\d)(u\\d+)\\+(b\\d+?)(@([a-f0-9]{32}))?"); + private static final Pattern EA_VERSION_PATTERN = Pattern.compile("(\\d+)-ea\\+(\\d+)(@([a-f0-9]{32}))?"); private final String name; private final FileCollection configuration; @@ -78,7 +79,9 @@ public String getVersion() { } public void setVersion(String version) { - if (VERSION_PATTERN.matcher(version).matches() == false && LEGACY_VERSION_PATTERN.matcher(version).matches() == false) { + if (VERSION_PATTERN.matcher(version).matches() == false + && LEGACY_VERSION_PATTERN.matcher(version).matches() == false + && EA_VERSION_PATTERN.matcher(version).matches() == false) { throw new IllegalArgumentException("malformed version [" + version + "] for jdk [" + name + "]"); } parseVersion(version); @@ -218,9 +221,17 @@ private void parseVersion(String version) { if (jdkVersionMatcher.matches() == false) { // Try again with the pre-Java9 version format jdkVersionMatcher = LEGACY_VERSION_PATTERN.matcher(version); - if (jdkVersionMatcher.matches() == false) { - throw new IllegalArgumentException("Malformed jdk version [" + version + "]"); + // Try again with the pre-Java9 version format + jdkVersionMatcher = EA_VERSION_PATTERN.matcher(version); + if (jdkVersionMatcher.matches() == false) { + throw new IllegalArgumentException("Malformed jdk version [" + version + "]"); + } + baseVersion = version; + major = jdkVersionMatcher.group(1); + build = jdkVersionMatcher.group(2); + hash = null; + return; } } diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/JdkDownloadPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/JdkDownloadPlugin.java index 3c278128e43f2..acfbfc30ae291 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/JdkDownloadPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/JdkDownloadPlugin.java @@ -114,6 +114,19 @@ private void setupRepository(Project project, Jdk jdk) { + jdk.getBuild() + "/[module]/[classifier]/jdk/hotspot/normal/adoptium"; } + } else if (jdk.getVendor().equals(VENDOR_OPENJDK) && jdk.getDistributionVersion().equals("ea")) { + + // "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+30/openjdk-25-ea+30_linux-x64_bin.tar.gz"], + // /jdks/openjdk/25/openjdk-25-ea+30/openjdk-25-ea+30_linux + repoUrl = "https://builds.es-jdk-archive.com/"; + + // current pattern since 12.0.1 + artifactPattern = "jdks/openjdk/" + + jdk.getMajor() + + "/openjdk-" + + jdk.getBaseVersion() + + "/" + + "openjdk-[revision]_[module]-[classifier]_bin.[ext]"; } else if (jdk.getVendor().equals(VENDOR_OPENJDK)) { repoUrl = "https://download.oracle.com"; if (jdk.getHash() != null) { diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java index 404d61a03f1c7..d229d2da2d097 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java @@ -12,8 +12,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.io.IOUtils; +import org.elasticsearch.gradle.Architecture; +import org.elasticsearch.gradle.OS; import org.elasticsearch.gradle.VersionProperties; import org.elasticsearch.gradle.internal.BwcVersions; +import org.elasticsearch.gradle.internal.Jdk; +import org.elasticsearch.gradle.internal.JdkDownloadPlugin; import org.elasticsearch.gradle.internal.conventions.GitInfoPlugin; import org.elasticsearch.gradle.internal.conventions.info.GitInfo; import org.elasticsearch.gradle.internal.conventions.info.ParallelDetector; @@ -22,6 +26,7 @@ import org.gradle.api.Action; import org.gradle.api.GradleException; import org.gradle.api.JavaVersion; +import org.gradle.api.NamedDomainObjectContainer; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.logging.Logger; @@ -52,12 +57,14 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.UncheckedIOException; +import java.lang.reflect.Field; import java.nio.file.Files; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Random; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -94,6 +101,7 @@ public GlobalBuildInfoPlugin( @Override public void apply(Project project) { + if (project != project.getRootProject()) { throw new IllegalStateException(this.getClass().getName() + " can only be applied to the root project."); } @@ -272,7 +280,9 @@ private JavaVersion determineJavaVersion(String description, File javaHome, Java private InstallationLocation getJavaInstallation(File javaHome) { return getAvailableJavaInstallationLocationSteam().filter(installationLocation -> isSameFile(javaHome, installationLocation)) .findFirst() - .orElseThrow(() -> new GradleException("Could not locate available Java installation in Gradle registry at: " + javaHome)); + .orElse( + InstallationLocation.userDefined(javaHome, "Manually resolved JavaHome (not auto-detected by Gradle toolchain service)") + ); } private boolean isSameFile(File javaHome, InstallationLocation installationLocation) { @@ -337,11 +347,15 @@ private static void assertMinimumCompilerVersion(JavaVersion minimumCompilerVers } private Provider findRuntimeJavaHome() { - String runtimeJavaProperty = System.getProperty("runtime.java"); - + Integer runtimeJavaProperty = Integer.getInteger("runtime.java"); if (runtimeJavaProperty != null) { - System.out.println("GlobalBuildInfoPlugin.findRuntimeJavaHome"); - return resolveJavaHomeFromToolChainService(runtimeJavaProperty); + if (runtimeJavaProperty > Integer.parseInt(VersionProperties.getBundledJdkMajorVersion())) { + // handle EA builds differently due to lack of support in Gradle toolchain service + // we resolve them using JdkDownloadPlugin for now. + return resolveEarlyAccessJavaHome(runtimeJavaProperty); + } else { + return resolveJavaHomeFromToolChainService(runtimeJavaProperty.toString()); + } } if (System.getenv("RUNTIME_JAVA_HOME") != null) { return providers.provider(() -> new File(System.getenv("RUNTIME_JAVA_HOME"))); @@ -356,28 +370,31 @@ private Provider findRuntimeJavaHome() { }); } + private Provider resolveEarlyAccessJavaHome(Integer runtimeJavaProperty) { + NamedDomainObjectContainer container = project.getPlugins().apply(JdkDownloadPlugin.class).getContainer(project); + Integer buildNumber = Integer.getInteger("runtime.java.build"); + if (buildNumber == null) { + buildNumber = Integer.getInteger("runtime.java." + runtimeJavaProperty + ".build"); + } + if (buildNumber == null) { + buildNumber = findLatestEABuildNumber(runtimeJavaProperty); + } + String eaVersionString = String.format("%d-ea+%d", runtimeJavaProperty, buildNumber); + Jdk jdk = container.create("ea_jdk_" + runtimeJavaProperty, j -> { + j.setVersion(eaVersionString); + j.setVendor("openjdk"); + j.setPlatform(OS.current().javaOsReference); + j.setArchitecture(Architecture.current().javaClassifier); + j.setDistributionVersion("ea"); + }); + return providers.provider(() -> new File(jdk.getJavaHomePath().toString())); + } + @NotNull private Provider resolveJavaHomeFromToolChainService(String version) { - JavaLanguageVersion languageVersion = JavaLanguageVersion.of(version); - Property value = objectFactory.property(JavaLanguageVersion.class).value(languageVersion); - return toolChainService.launcherFor(javaToolchainSpec -> { - javaToolchainSpec.getLanguageVersion().value(value); - - if (Integer.parseInt(VersionProperties.getBundledJdkMajorVersion()) < Integer.parseInt(version)) { - // If the requested version is higher than the bundled JDK, we need trick the toolchain into using our early access catalog - // Otherwise, we use the default implementation - Integer buildNumber = Integer.getInteger("runtime.java.build"); - - if (buildNumber == null) { - buildNumber = Integer.getInteger("runtime.java." + version + ".build"); - } - if (buildNumber == null) { - buildNumber = findLatestEABuildNumber(languageVersion); - } - javaToolchainSpec.getVendor() - .set(DefaultJvmVendorSpec.of("Oracle[" + languageVersion + "/" + buildNumber + "]")); - } - }).map(launcher -> launcher.getMetadata().getInstallationPath().getAsFile()); + Property value = objectFactory.property(JavaLanguageVersion.class).value(JavaLanguageVersion.of(version)); + return toolChainService.launcherFor(javaToolchainSpec -> javaToolchainSpec.getLanguageVersion().value(value)) + .map(launcher -> launcher.getMetadata().getInstallationPath().getAsFile()); } public static String getResourceContents(String resourcePath) { diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolver.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolver.java index 4bea812b2adc3..dace087b05842 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolver.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolver.java @@ -18,8 +18,6 @@ import org.gradle.jvm.toolchain.JavaToolchainDownload; import org.gradle.jvm.toolchain.JavaToolchainRequest; import org.gradle.jvm.toolchain.JavaToolchainSpec; -import org.gradle.jvm.toolchain.JvmVendorSpec; -import org.gradle.jvm.toolchain.internal.DefaultJvmVendorSpec; import org.gradle.platform.Architecture; import org.gradle.platform.BuildPlatform; import org.gradle.platform.OperatingSystem; @@ -32,9 +30,17 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +/** + * A toolchain resolver that resolves early access JDKs from the Elasticsearch JDK archive. + *

+ * This resolver can used to resolve JDKs that are not bundled with Elasticsearch but are available in the early access catalog. + * It supports resolving JDKs based on their language version and build number. + * + * Currently the gradle toolchain support does not support querying specific versions (e.g. 26-ea+6) so. For now + * this only supports resolving the latest early access build for a given language version. + *

+ */ public abstract class EarlyAccessCatalogJdkToolchainResolver extends AbstractCustomJavaToolchainResolver { interface JdkBuild { @@ -43,35 +49,9 @@ interface JdkBuild { String url(String os, String arch, String extension); } - private static final Pattern PATTERN = Pattern.compile("Oracle\\[(\\d+)/(\\d+)\\]"); - - public static class EaCatalogVendorSpec extends JvmVendorSpec { - - private final JavaLanguageVersion languageVersion; - private final int buildNumber; - - private EaCatalogVendorSpec(JavaLanguageVersion languageVersion, int buildNumber) { - this.languageVersion = languageVersion; - this.buildNumber = buildNumber; - } - - public static EaCatalogVendorSpec of(JavaLanguageVersion languageVersion, int buildNumber) { - return new EaCatalogVendorSpec(languageVersion, buildNumber); - } - - @Override - public boolean matches(String vendor) { - return false; - } - - public int getBuildNumber() { - return buildNumber; - } - } - @FunctionalInterface interface EarlyAccessJdkBuildResolver { - Optional findLatestEABuild(JavaLanguageVersion languageVersion); + Optional findLatestEABuild(JavaLanguageVersion languageVersion); } // allow overriding for testing @@ -109,14 +89,6 @@ public String url(String os, String arch, String extension) { OperatingSystem.WINDOWS ); - // static EarlyAccessJdkBuild getEarlyAccessBuild(JavaLanguageVersion languageVersion, String buildNumber) { - // // first try the unversioned override, then the versioned override which has higher precedence - // buildNumber = System.getProperty("runtime.java.build", buildNumber); - // buildNumber = System.getProperty("runtime.java." + languageVersion.asInt() + ".build", buildNumber); - // - // return new EarlyAccessJdkBuild(languageVersion, buildNumber); - // } - /** * We need some place to map JavaLanguageVersion to buildNumber, minor version etc. * */ @@ -141,7 +113,7 @@ public Optional resolve(JavaToolchainRequest request) { * Check if request can be full-filled by this resolver: * 1. Aarch64 windows images are not supported */ - private Optional findSupportedBuild(JavaToolchainRequest request) { + private Optional findSupportedBuild(JavaToolchainRequest request) { JavaToolchainSpec javaToolchainSpec = request.getJavaToolchainSpec(); BuildPlatform buildPlatform = request.getBuildPlatform(); Architecture architecture = buildPlatform.getArchitecture(); @@ -153,23 +125,10 @@ private Optional findSupportedBuild(JavaToolchainRequest req } JavaLanguageVersion languageVersion = javaToolchainSpec.getLanguageVersion().get(); - // resolve from vendor spec if available - if (javaToolchainSpec.getVendor().isPresent() && javaToolchainSpec.getVendor().get() instanceof DefaultJvmVendorSpec) { - DefaultJvmVendorSpec spec = (DefaultJvmVendorSpec) javaToolchainSpec.getVendor().get(); - String criteria = spec.toCriteria(); - Matcher matcher = PATTERN.matcher(criteria); - if (matcher.matches()) { - int level = Integer.parseInt(matcher.group(1)); - int build = Integer.parseInt(matcher.group(2)); - assert level == languageVersion.asInt() : "Language version does not match: " + level + " != " + languageVersion.asInt(); - return Optional.of(new EarlyAccessJdkBuild(languageVersion, build)); - } - } - return findLatestEABuild(languageVersion); + return earlyAccessJdkBuildResolver.findLatestEABuild(languageVersion); } private static Optional findLatestEABuild(JavaLanguageVersion languageVersion) { - System.out.println("CatalogJdkToolchainResolver.findLatestEABuild"); try { URL url = new URL("https://storage.googleapis.com/elasticsearch-jdk-archive/jdks/openjdk/latest.json"); try (InputStream is = url.openStream()) { @@ -195,7 +154,7 @@ private static Optional findLatestEABuild(JavaLanguageVersi } } - public static int findLatestEABuildNumber(JavaLanguageVersion languageVersion) { - return findLatestEABuild(languageVersion).map(ea -> ea.buildNumber()).get(); + public static int findLatestEABuildNumber(int languageVersion) { + return findLatestEABuild(JavaLanguageVersion.of(languageVersion)).map(ea -> ea.buildNumber()).get(); } } diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolver.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolver.java index 40d8178fcbd88..a0036529ad6fe 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolver.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolver.java @@ -58,26 +58,6 @@ public String url(String os, String arch, String extension) { } } - record EarlyAccessJdkBuild(JavaLanguageVersion languageVersion, String buildNumber) implements JdkBuild { - @Override - public String url(String os, String arch, String extension) { - return "https://download.java.net/java/early_access/jdk" - + languageVersion.asInt() - + "/" - + buildNumber - + "/GPL/openjdk-" - + languageVersion.asInt() - + "-ea+" - + buildNumber - + "_" - + os - + "-" - + arch - + "_bin." - + extension; - } - } - private static final Pattern VERSION_PATTERN = Pattern.compile( "(\\d+)(\\.\\d+\\.\\d+(?:\\.\\d+)?)?\\+(\\d+(?:\\.\\d+)?)(@([a-f0-9]{32}))?" ); @@ -93,14 +73,6 @@ public String url(String os, String arch, String extension) { getBundledJdkBuild(VersionProperties.getBundledJdkVersion(), VersionProperties.getBundledJdkMajorVersion()) ); - static EarlyAccessJdkBuild getEarlyAccessBuild(JavaLanguageVersion languageVersion, String buildNumber) { - // first try the unversioned override, then the versioned override which has higher precedence - buildNumber = System.getProperty("runtime.java.build", buildNumber); - buildNumber = System.getProperty("runtime.java." + languageVersion.asInt() + ".build", buildNumber); - - return new EarlyAccessJdkBuild(languageVersion, buildNumber); - } - static JdkBuild getBundledJdkBuild(String bundledJdkVersion, String bundledJkdMajorVersionString) { JavaLanguageVersion bundledJdkMajorVersion = JavaLanguageVersion.of(bundledJkdMajorVersionString); Matcher jdkVersionMatcher = VERSION_PATTERN.matcher(bundledJdkVersion); diff --git a/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/JdkSpec.groovy b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/JdkSpec.groovy new file mode 100644 index 0000000000000..72aebda2e0b80 --- /dev/null +++ b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/JdkSpec.groovy @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.gradle.internal + +import spock.lang.Specification + +import org.gradle.api.artifacts.Configuration +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Property + +class JdkSpec extends Specification { + + def "jdk version is parsed correctly"() { + given: + Jdk jdk = newJdk() + + when: + jdk.setVersion(version) + then: + jdk.getBaseVersion() == baseVersion + jdk.getBuild() == buildNumber + + where: + version | baseVersion | major | buildNumber + "25-ea+30" | "25-ea+30" | "25" | "30" + "26-ea+6" | "26-ea+6" | "26" | "6" + } + + Object newJdk(String name = "jdk") { + Configuration configuration = Mock() + _ * configuration.getName() >> name + "Config" + + ObjectFactory objectFactory = Mock() + Property stringProperty = Mock() + _ * objectFactory.property(String.class) >> stringProperty + + return new Jdk(name, configuration, objectFactory) + } +} diff --git a/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolverSpec.groovy b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolverSpec.groovy index 295abc9c6d968..aaf71c41e5087 100644 --- a/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolverSpec.groovy +++ b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/EarlyAccessCatalogJdkToolchainResolverSpec.groovy @@ -9,6 +9,7 @@ package org.elasticsearch.gradle.internal.toolchain +import org.elasticsearch.gradle.VersionProperties import org.gradle.api.services.BuildServiceParameters import org.gradle.jvm.toolchain.JavaLanguageVersion import org.gradle.jvm.toolchain.JavaToolchainResolver @@ -27,42 +28,35 @@ class EarlyAccessCatalogJdkToolchainResolverSpec extends AbstractToolchainResolv return null } } - resolver.earlyAccessJdkBuildResolver = () -> { + resolver.earlyAccessJdkBuildResolver = (JavaLanguageVersion version) -> { return Optional.of( - new EarlyAccessCatalogJdkToolchainResolver.EarlyAccessJdkBuild(JavaLanguageVersion.of(25), 31), - new EarlyAccessCatalogJdkToolchainResolver.EarlyAccessJdkBuild(JavaLanguageVersion.of(26), 6) + new EarlyAccessCatalogJdkToolchainResolver.EarlyAccessJdkBuild(version, 30) ) } return resolver } - def anyVendorMatch() { - return JvmVendorSpec.ANY - } @Override def supportedRequests() { return [ - [25, vSpec( - 25, - 30 - ), LINUX, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+30/openjdk-25-ea+30_linux-x64_bin.tar.gz"], - [26, vSpec( - 26, - 6 - ), WINDOWS, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/26/openjdk-26-ea+6/openjdk-26-ea+6_windows-x64_bin.zip"], - [26, vSpec( - 26, - 6 - ), MAC_OS, AARCH64, "https://builds.es-jdk-archive.com/jdks/openjdk/26/openjdk-26-ea+6/openjdk-26-ea+6_macos-aarch64_bin.tar.gz"] - ] - } + [25, anyVendor(), LINUX, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+30/openjdk-25-ea+30_linux-x64_bin.tar.gz"], + [25, anyVendor(), LINUX, AARCH64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+30/openjdk-25-ea+30_linux-aarch64_bin.tar.gz"], + [25, anyVendor(), MAC_OS, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+30/openjdk-25-ea+30_macos-x64_bin.tar.gz"], + [25, anyVendor(), MAC_OS, AARCH64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+30/openjdk-25-ea+30_macos-aarch64_bin.tar.gz"], + [25, anyVendor(), WINDOWS, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+30/openjdk-25-ea+30_windows-x64_bin.zip"], - private JvmVendorSpec vSpec(int version, int build) { - return org.gradle.jvm.toolchain.internal.DefaultJvmVendorSpec.of("EarlyAccessJvmCatalog[" + version + "/" + build + "]"); + [26, anyVendor(), LINUX, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/26/openjdk-26-ea+30/openjdk-26-ea+30_linux-x64_bin.tar.gz"], + [26, anyVendor(), LINUX, AARCH64, "https://builds.es-jdk-archive.com/jdks/openjdk/26/openjdk-26-ea+30/openjdk-26-ea+30_linux-aarch64_bin.tar.gz"], + [26, anyVendor(), MAC_OS, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/26/openjdk-26-ea+30/openjdk-26-ea+30_macos-x64_bin.tar.gz"], + [26, anyVendor(), MAC_OS, AARCH64, "https://builds.es-jdk-archive.com/jdks/openjdk/26/openjdk-26-ea+30/openjdk-26-ea+30_macos-aarch64_bin.tar.gz"], + [26, anyVendor(), WINDOWS, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/26/openjdk-26-ea+30/openjdk-26-ea+30_windows-x64_bin.zip"] + ] } @Override def unsupportedRequests() { - return [] + [ + [Integer.parseInt(VersionProperties.bundledJdkMajorVersion) + 1, anyVendor(), WINDOWS, AARCH64], + ] } } diff --git a/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolverSpec.groovy b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolverSpec.groovy index df9f70d0a47f6..5520358631e04 100644 --- a/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolverSpec.groovy +++ b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolverSpec.groovy @@ -9,11 +9,9 @@ package org.elasticsearch.gradle.internal.toolchain -import spock.util.environment.RestoreSystemProperties import org.gradle.api.services.BuildServiceParameters import org.gradle.jvm.toolchain.JavaLanguageVersion -import org.gradle.jvm.toolchain.JavaToolchainDownload import static org.gradle.jvm.toolchain.JvmVendorSpec.ORACLE import static org.gradle.platform.Architecture.AARCH64 @@ -22,7 +20,6 @@ import static org.gradle.platform.OperatingSystem.* class OracleOpenJdkToolchainResolverSpec extends AbstractToolchainResolverSpec { - OracleOpenJdkToolchainResolver resolverImplementation() { var toolChain = new OracleOpenJdkToolchainResolver() { @Override @@ -39,7 +36,6 @@ class OracleOpenJdkToolchainResolverSpec extends AbstractToolchainResolverSpec { "bdc68b4b9cbc4ebcb30745c85038d91d" ), OracleOpenJdkToolchainResolver.getBundledJdkBuild("24+36@1f9ff9062db4449d8ca828c504ffae90", "24"), - OracleOpenJdkToolchainResolver.getEarlyAccessBuild(JavaLanguageVersion.of(25), "3") ] toolChain } @@ -65,51 +61,8 @@ class OracleOpenJdkToolchainResolverSpec extends AbstractToolchainResolverSpec { [24, anyVendor(), MAC_OS, AARCH64, "https://download.oracle.com/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_macos-aarch64_bin.tar.gz"], [24, anyVendor(), LINUX, X86_64, "https://download.oracle.com/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_linux-x64_bin.tar.gz"], [24, anyVendor(), LINUX, AARCH64, "https://download.oracle.com/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_linux-aarch64_bin.tar.gz"], - [24, anyVendor(), WINDOWS, X86_64, "https://download.oracle.com/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_windows-x64_bin.zip"], - // EA build - [25, ORACLE, MAC_OS, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+3/openjdk-25-ea+3_macos-x64_bin.tar.gz"], - [25, ORACLE, MAC_OS, AARCH64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+3/openjdk-25-ea+3_macos-aarch64_bin.tar.gz"], - [25, ORACLE, LINUX, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+3/openjdk-25-ea+3_linux-x64_bin.tar.gz"], - [25, ORACLE, LINUX, AARCH64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+3/openjdk-25-ea+3_linux-aarch64_bin.tar.gz"], - [25, ORACLE, WINDOWS, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+3/openjdk-25-ea+3_windows-x64_bin.zip"], - [25, anyVendor(), MAC_OS, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+3/openjdk-25-ea+3_macos-x64_bin.tar.gz"], - [25, anyVendor(), MAC_OS, AARCH64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+3/openjdk-25-ea+3_macos-aarch64_bin.tar.gz"], - [25, anyVendor(), LINUX, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+3/openjdk-25-ea+3_linux-x64_bin.tar.gz"], - [25, anyVendor(), LINUX, AARCH64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+3/openjdk-25-ea+3_linux-aarch64_bin.tar.gz"], - [25, anyVendor(), WINDOWS, X86_64, "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+3/openjdk-25-ea+3_windows-x64_bin.zip"]] - } - - @RestoreSystemProperties - def "can provide build number for ea versions"() { - given: - System.setProperty('runtime.java.build', "42") - System.setProperty('runtime.java.25.build', "13") - def resolver = resolverImplementation() - - when: - Optional download = resolver.resolve( - request( - JavaLanguageVersion.of(version), - vendor, - platform(os, arch) - ) - ) - - then: - download.get().uri == URI.create(expectedUrl) - - where: - version | vendor | os | arch | expectedUrl - 25 | ORACLE | MAC_OS | X86_64 | urlPrefix(25) + "openjdk-25-ea+13/openjdk-25-ea+13_macos-x64_bin.tar.gz" - 25 | ORACLE | MAC_OS | AARCH64 | urlPrefix(25) + "openjdk-25-ea+13/openjdk-25-ea+13_macos-aarch64_bin.tar.gz" - 25 | ORACLE | LINUX | X86_64 | urlPrefix(25) + "openjdk-25-ea+13/openjdk-25-ea+13_linux-x64_bin.tar.gz" - 25 | ORACLE | LINUX | AARCH64 | urlPrefix(25) + "openjdk-25-ea+13/openjdk-25-ea+13_linux-aarch64_bin.tar.gz" - 25 | ORACLE | WINDOWS | X86_64 | urlPrefix(25) + "openjdk-25-ea+13/openjdk-25-ea+13_windows-x64_bin.zip" - 25 | anyVendor() | MAC_OS | X86_64 | urlPrefix(25) + "openjdk-25-ea+13/openjdk-25-ea+13_macos-x64_bin.tar.gz" - 25 | anyVendor() | MAC_OS | AARCH64 | urlPrefix(25) + "openjdk-25-ea+13/openjdk-25-ea+13_macos-aarch64_bin.tar.gz" - 25 | anyVendor() | LINUX | X86_64 | urlPrefix(25) + "openjdk-25-ea+13/openjdk-25-ea+13_linux-x64_bin.tar.gz" - 25 | anyVendor() | LINUX | AARCH64 | urlPrefix(25) + "openjdk-25-ea+13/openjdk-25-ea+13_linux-aarch64_bin.tar.gz" - 25 | anyVendor() | WINDOWS | X86_64 | urlPrefix(25) + "openjdk-25-ea+13/openjdk-25-ea+13_windows-x64_bin.zip" + [24, anyVendor(), WINDOWS, X86_64, "https://download.oracle.com/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_windows-x64_bin.zip"] + ] } private static String urlPrefix(int i) { diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/Architecture.java b/build-tools/src/main/java/org/elasticsearch/gradle/Architecture.java index ae47f934b0dc3..c2654f9ae851f 100644 --- a/build-tools/src/main/java/org/elasticsearch/gradle/Architecture.java +++ b/build-tools/src/main/java/org/elasticsearch/gradle/Architecture.java @@ -11,17 +11,19 @@ public enum Architecture { - X64("x86_64", "linux/amd64", "amd64"), - AARCH64("aarch64", "linux/arm64", "arm64"); + X64("x86_64", "linux/amd64", "amd64", "x64"), + AARCH64("aarch64", "linux/arm64", "arm64", "aarch64"); public final String classifier; public final String dockerPlatform; public final String dockerClassifier; + public final String javaClassifier; - Architecture(String classifier, String dockerPlatform, String dockerClassifier) { + Architecture(String classifier, String dockerPlatform, String dockerClassifier, String javaClassifier) { this.classifier = classifier; this.dockerPlatform = dockerPlatform; this.dockerClassifier = dockerClassifier; + this.javaClassifier = javaClassifier; } public static Architecture current() { diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/DistributionDownloadPlugin.java b/build-tools/src/main/java/org/elasticsearch/gradle/DistributionDownloadPlugin.java index 35748459ecac3..838752a515b05 100644 --- a/build-tools/src/main/java/org/elasticsearch/gradle/DistributionDownloadPlugin.java +++ b/build-tools/src/main/java/org/elasticsearch/gradle/DistributionDownloadPlugin.java @@ -191,10 +191,12 @@ private static void addIvyRepo(Project project, String name, String url, String repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); repo.patternLayout(layout -> layout.artifact("/downloads/elasticsearch/[module]-[revision](-[classifier]).[ext]")); }); - project.getRepositories().exclusiveContent(exclusiveContentRepository -> { - exclusiveContentRepository.filter(config -> config.includeGroup(group)); - exclusiveContentRepository.forRepositories(ivyRepo); - }); + if (project != project.getRootProject()) { + project.getRepositories().exclusiveContent(exclusiveContentRepository -> { + exclusiveContentRepository.filter(config -> config.includeGroup(group)); + exclusiveContentRepository.forRepositories(ivyRepo); + }); + } } private static void setupDownloadServiceRepo(Project project) { diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/OS.java b/build-tools/src/main/java/org/elasticsearch/gradle/OS.java index d5649f94cf1a4..fda24687ad4e8 100644 --- a/build-tools/src/main/java/org/elasticsearch/gradle/OS.java +++ b/build-tools/src/main/java/org/elasticsearch/gradle/OS.java @@ -15,9 +15,16 @@ import java.util.function.Supplier; public enum OS { - WINDOWS, - MAC, - LINUX; + WINDOWS("windows"), + MAC("darwin"), + LINUX("linux"); + + public final String javaOsReference; + + OS(String javaOsReference) { + // This constructor is intentionally empty, but it can be used to set up any necessary state. + this.javaOsReference = javaOsReference; + } public static OS current() { String os = System.getProperty("os.name", ""); diff --git a/build.gradle b/build.gradle index f598b6e83a9ca..60aac98ac3203 100644 --- a/build.gradle +++ b/build.gradle @@ -35,11 +35,11 @@ buildscript { plugins { id 'lifecycle-base' id 'elasticsearch.docker-support' + id 'elasticsearch.internal-distribution-download' + id 'elasticsearch.jdk-download' id 'elasticsearch.global-build-info' id 'elasticsearch.build-complete' id 'elasticsearch.build-scan' - id 'elasticsearch.jdk-download' - id 'elasticsearch.internal-distribution-download' id 'elasticsearch.runtime-jdk-provision' id 'elasticsearch.ide' id 'elasticsearch.forbidden-dependencies' diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index b3413a72885cc..54c6bf052ef43 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -9,6 +9,8 @@ + + diff --git a/settings.gradle b/settings.gradle index 36ef9809e0152..379c24ce6e1ee 100644 --- a/settings.gradle +++ b/settings.gradle @@ -43,9 +43,6 @@ toolchainManagement { repository('archivedOracleJdks') { resolverClass = ArchivedOracleJdkToolchainResolver } - repository('EarlyAccessCatalogJdks') { - resolverClass = EarlyAccessCatalogJdkToolchainResolver - } } } } diff --git a/test/immutable-collections-patch/build.gradle b/test/immutable-collections-patch/build.gradle index 852a19116fb71..219f9452f483a 100644 --- a/test/immutable-collections-patch/build.gradle +++ b/test/immutable-collections-patch/build.gradle @@ -31,16 +31,12 @@ generatePatch.configure { classpath = sourceSets.main.runtimeClasspath mainClass = 'org.elasticsearch.jdk.patch.ImmutableCollectionsPatcher' - if (buildParams.getIsRuntimeJavaHomeSet()) { - executable = "${buildParams.runtimeJavaHome.get()}/bin/java" + (OS.current() == OS.WINDOWS ? '.exe' : '') - } else { javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(VersionProperties.bundledJdkMajorVersion) vendor = VersionProperties.bundledJdkVendor == "openjdk" ? JvmVendorSpec.ORACLE : JvmVendorSpec.matching(VersionProperties.bundledJdkVendor) } - } doFirst { args outputDir.get().getAsFile().toString() } From bbd4287e12c8fc8e1583d6f4a18f9eff0ead9b64 Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Wed, 13 Aug 2025 19:11:00 +0200 Subject: [PATCH 3/8] Minor cleanup and fixing non set distribution type in jdk --- .../main/java/org/elasticsearch/gradle/internal/Jdk.java | 2 +- .../elasticsearch/gradle/internal/JdkDownloadPlugin.java | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/Jdk.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/Jdk.java index 60d034ca4da74..1da7d2729bd4e 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/Jdk.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/Jdk.java @@ -115,7 +115,7 @@ public void setArchitecture(final String architecture) { } public String getDistributionVersion() { - return distributionVersion.get(); + return distributionVersion.getOrNull(); } public void setDistributionVersion(String distributionVersion) { diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/JdkDownloadPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/JdkDownloadPlugin.java index acfbfc30ae291..363866a3a3df1 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/JdkDownloadPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/JdkDownloadPlugin.java @@ -114,12 +114,8 @@ private void setupRepository(Project project, Jdk jdk) { + jdk.getBuild() + "/[module]/[classifier]/jdk/hotspot/normal/adoptium"; } - } else if (jdk.getVendor().equals(VENDOR_OPENJDK) && jdk.getDistributionVersion().equals("ea")) { - - // "https://builds.es-jdk-archive.com/jdks/openjdk/25/openjdk-25-ea+30/openjdk-25-ea+30_linux-x64_bin.tar.gz"], - // /jdks/openjdk/25/openjdk-25-ea+30/openjdk-25-ea+30_linux + } else if (jdk.getVendor().equals(VENDOR_OPENJDK) && "ea".equals(jdk.getDistributionVersion())) { repoUrl = "https://builds.es-jdk-archive.com/"; - // current pattern since 12.0.1 artifactPattern = "jdks/openjdk/" + jdk.getMajor() From ba8882d43c206bb9757b34592a9a10f317175277 Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Thu, 14 Aug 2025 09:28:08 +0200 Subject: [PATCH 4/8] Fix ea jdk selection not just based on major version explicitly requires to add a ea postfix to the runtime sys property --- BUILDING.md | 8 ++++---- .../gradle/internal/info/GlobalBuildInfoPlugin.java | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index a71622687738f..1afe6a5e833b4 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -189,11 +189,11 @@ To test an unreleased development version of a third party dependency you have s ### How do I test against java early access (ea) versions? Currently only openjdk EA builds by oracle are supported. -To test against an early access version java version you can pass the major java version -to test against via system property (e.g. -Druntime.java=26): +To test against an early access version java version you can pass the major +java version appended with `-ea` as a system property (e.g. -Druntime.java=26-ea) to the Gradle build: ``` -./gradlew clean test -Druntime.java=26 +./gradlew clean test -Druntime.java=26-ea ``` This will run the tests using the JDK 26 EA version and pick the latest available build of the matching JDK EA version we expose @@ -202,7 +202,7 @@ in our custom jdk catalogue at `https://storage.googleapis.com/elasticsearch-jdk To run against a specific build number of the EA build you can pass a second system property (e.g. `-Druntime.java.build=6`): ``` -./gradlew clean test -Druntime.java=26 -Druntime.java.build=6 +./gradlew clean test -Druntime.java=26-ea -Druntime.java.build=6 ``` #### How to use a Maven based third party dependency via `mavenlocal`? diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java index d229d2da2d097..6c9e70451f9a8 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java @@ -347,14 +347,16 @@ private static void assertMinimumCompilerVersion(JavaVersion minimumCompilerVers } private Provider findRuntimeJavaHome() { - Integer runtimeJavaProperty = Integer.getInteger("runtime.java"); + String runtimeJavaProperty = System.getProperty("runtime.java"); + if (runtimeJavaProperty != null) { - if (runtimeJavaProperty > Integer.parseInt(VersionProperties.getBundledJdkMajorVersion())) { + if(runtimeJavaProperty.toLowerCase().endsWith("-ea")) { // handle EA builds differently due to lack of support in Gradle toolchain service // we resolve them using JdkDownloadPlugin for now. - return resolveEarlyAccessJavaHome(runtimeJavaProperty); + Integer major = Integer.parseInt(runtimeJavaProperty.substring(0, runtimeJavaProperty.length() - 3)); + return resolveEarlyAccessJavaHome(major); } else { - return resolveJavaHomeFromToolChainService(runtimeJavaProperty.toString()); + return resolveJavaHomeFromToolChainService(runtimeJavaProperty); } } if (System.getenv("RUNTIME_JAVA_HOME") != null) { From 81b56f2852764bb9d206286f80e5767ee439ab09 Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Thu, 14 Aug 2025 10:36:02 +0200 Subject: [PATCH 5/8] Fix test reproduce linies when using java ea version --- .../test/junit/listeners/ReproduceInfoPrinter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/framework/src/main/java/org/elasticsearch/test/junit/listeners/ReproduceInfoPrinter.java b/test/framework/src/main/java/org/elasticsearch/test/junit/listeners/ReproduceInfoPrinter.java index 00620d5b9c3dd..6a1e700335e7e 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/junit/listeners/ReproduceInfoPrinter.java +++ b/test/framework/src/main/java/org/elasticsearch/test/junit/listeners/ReproduceInfoPrinter.java @@ -190,9 +190,11 @@ private ReproduceErrorMessageBuilder appendESProperties() { appendOpt("tests.locale", Locale.getDefault().toLanguageTag()); appendOpt("tests.timezone", TimeZone.getDefault().getID()); appendOpt("tests.distribution", System.getProperty("tests.distribution")); - appendOpt("runtime.java", Integer.toString(Runtime.version().feature())); if (Runtime.version().build().isPresent() && "ea".equalsIgnoreCase(Runtime.version().pre().orElse(""))) { + appendOpt("runtime.java", Runtime.version().feature() + "-ea"); appendOpt("runtime.java.build", Integer.toString(Runtime.version().build().get())); + } else { + appendOpt("runtime.java", Integer.toString(Runtime.version().feature())); } appendOpt(ESTestCase.FIPS_SYSPROP, System.getProperty(ESTestCase.FIPS_SYSPROP)); return this; From a2bc8fe57b70cdc27971b525b00a9db197a186de Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Thu, 14 Aug 2025 23:17:09 +0200 Subject: [PATCH 6/8] Apply review feedback --- .../gradle/internal/info/GlobalBuildInfoPlugin.java | 3 --- gradle/verification-metadata.xml | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java index 6c9e70451f9a8..af74e7bd47f80 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java @@ -375,9 +375,6 @@ private Provider findRuntimeJavaHome() { private Provider resolveEarlyAccessJavaHome(Integer runtimeJavaProperty) { NamedDomainObjectContainer container = project.getPlugins().apply(JdkDownloadPlugin.class).getContainer(project); Integer buildNumber = Integer.getInteger("runtime.java.build"); - if (buildNumber == null) { - buildNumber = Integer.getInteger("runtime.java." + runtimeJavaProperty + ".build"); - } if (buildNumber == null) { buildNumber = findLatestEABuildNumber(runtimeJavaProperty); } diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 54c6bf052ef43..ff3a06c604a06 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -9,8 +9,7 @@ - - + From 4610d7bfba822a1d7004d5b61e9c404dc16267cb Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Thu, 14 Aug 2025 23:22:50 +0200 Subject: [PATCH 7/8] Use runtime jdk when patching --- test/immutable-collections-patch/build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/immutable-collections-patch/build.gradle b/test/immutable-collections-patch/build.gradle index 219f9452f483a..852a19116fb71 100644 --- a/test/immutable-collections-patch/build.gradle +++ b/test/immutable-collections-patch/build.gradle @@ -31,12 +31,16 @@ generatePatch.configure { classpath = sourceSets.main.runtimeClasspath mainClass = 'org.elasticsearch.jdk.patch.ImmutableCollectionsPatcher' + if (buildParams.getIsRuntimeJavaHomeSet()) { + executable = "${buildParams.runtimeJavaHome.get()}/bin/java" + (OS.current() == OS.WINDOWS ? '.exe' : '') + } else { javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(VersionProperties.bundledJdkMajorVersion) vendor = VersionProperties.bundledJdkVendor == "openjdk" ? JvmVendorSpec.ORACLE : JvmVendorSpec.matching(VersionProperties.bundledJdkVendor) } + } doFirst { args outputDir.get().getAsFile().toString() } From 487a053fc091c5c545d3c9599638afb91bf6bcfc Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Thu, 14 Aug 2025 23:29:40 +0200 Subject: [PATCH 8/8] More cleanup --- .../gradle/internal/info/GlobalBuildInfoPlugin.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java index af74e7bd47f80..2c0c5ebb67248 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java @@ -45,7 +45,6 @@ import org.gradle.jvm.toolchain.JavaToolchainService; import org.gradle.jvm.toolchain.JavaToolchainSpec; import org.gradle.jvm.toolchain.JvmVendorSpec; -import org.gradle.jvm.toolchain.internal.DefaultJvmVendorSpec; import org.gradle.jvm.toolchain.internal.InstallationLocation; import org.gradle.util.GradleVersion; import org.jetbrains.annotations.NotNull; @@ -57,14 +56,12 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.UncheckedIOException; -import java.lang.reflect.Field; import java.nio.file.Files; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Random; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -107,6 +104,7 @@ public void apply(Project project) { } this.project = project; project.getPlugins().apply(JvmToolchainsPlugin.class); + project.getPlugins().apply(JdkDownloadPlugin.class); Provider gitInfo = project.getPlugins().apply(GitInfoPlugin.class).getGitInfo(); toolChainService = project.getExtensions().getByType(JavaToolchainService.class); @@ -350,7 +348,7 @@ private Provider findRuntimeJavaHome() { String runtimeJavaProperty = System.getProperty("runtime.java"); if (runtimeJavaProperty != null) { - if(runtimeJavaProperty.toLowerCase().endsWith("-ea")) { + if (runtimeJavaProperty.toLowerCase().endsWith("-ea")) { // handle EA builds differently due to lack of support in Gradle toolchain service // we resolve them using JdkDownloadPlugin for now. Integer major = Integer.parseInt(runtimeJavaProperty.substring(0, runtimeJavaProperty.length() - 3)); @@ -373,7 +371,7 @@ private Provider findRuntimeJavaHome() { } private Provider resolveEarlyAccessJavaHome(Integer runtimeJavaProperty) { - NamedDomainObjectContainer container = project.getPlugins().apply(JdkDownloadPlugin.class).getContainer(project); + NamedDomainObjectContainer container = (NamedDomainObjectContainer) project.getExtensions().getByName("jdks"); Integer buildNumber = Integer.getInteger("runtime.java.build"); if (buildNumber == null) { buildNumber = findLatestEABuildNumber(runtimeJavaProperty);