From 4e2f852c08565b02ff49a646373411e6f2926c03 Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Wed, 3 May 2023 15:28:47 +0200 Subject: [PATCH] Resolve runtime java via Gradle tool chain provider (#95319) Using gradle toolchain support in gradle requires refactoring how the composite build is composed. We added three toolchain resolver 1. Resolver for resolving defined bundled version from oracle as openjdk 2. Resolve all available jdks from Adoption 3. Resolve archived Oracle jdk distributions. We should be able to remove the JdkDownloadPlugin altogether without having that in place, but we'll do that in a separate effort. Fixes #95094 --- .../internal/conventions/GitInfoPlugin.java | 6 +- .../internal/conventions/util/Util.java | 36 +++-- build-tools-internal/build.gradle | 4 + build-tools-internal/settings.gradle | 5 + .../src/main/groovy/elasticsearch.ide.gradle | 14 +- ...elasticsearch.runtime-jdk-provision.gradle | 8 +- .../gradle/internal/JdkDownloadPlugin.java | 8 +- .../internal/info/GlobalBuildInfoPlugin.java | 42 +++++- .../AbstractCustomJavaToolchainResolver.java | 42 ++++++ .../AdoptiumJdkToolchainResolver.java | 125 ++++++++++++++++++ .../ArchivedOracleJdkToolchainResolver.java | 82 ++++++++++++ .../JavaToolChainResolverPlugin.java | 28 ++++ .../OracleOpenJdkToolchainResolver.java | 99 ++++++++++++++ .../AbstractToolchainResolverSpec.groovy | 107 +++++++++++++++ .../AdoptiumJdkToolchainResolverSpec.groovy | 83 ++++++++++++ ...hivedOracleJdkToolchainResolverSpec.groovy | 62 +++++++++ .../OracleOpenJdkToolchainResolverSpec.groovy | 51 +++++++ build-tools/settings.gradle | 4 + .../gradle/VersionProperties.java | 7 + build.gradle | 2 - settings.gradle | 29 +++- test/test-clusters/build.gradle | 2 +- 22 files changed, 807 insertions(+), 39 deletions(-) create mode 100644 build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/AbstractCustomJavaToolchainResolver.java create mode 100644 build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolver.java create mode 100644 build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/ArchivedOracleJdkToolchainResolver.java create mode 100644 build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/JavaToolChainResolverPlugin.java create mode 100644 build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolver.java create mode 100644 build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/AbstractToolchainResolverSpec.groovy create mode 100644 build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolverSpec.groovy create mode 100644 build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/ArchivedOracleJdkToolchainResolverSpec.groovy create mode 100644 build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolverSpec.groovy diff --git a/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/GitInfoPlugin.java b/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/GitInfoPlugin.java index db8002ba2afaa..a0fb8ee0504a6 100644 --- a/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/GitInfoPlugin.java +++ b/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/GitInfoPlugin.java @@ -9,6 +9,7 @@ package org.elasticsearch.gradle.internal.conventions; import org.elasticsearch.gradle.internal.conventions.info.GitInfo; +import org.elasticsearch.gradle.internal.conventions.util.Util; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.model.ObjectFactory; @@ -35,10 +36,7 @@ class GitInfoPlugin implements Plugin { @Override public void apply(Project project) { - File rootDir = (project.getGradle().getParent() == null) ? - project.getRootDir() : - project.getGradle().getParent().getRootProject().getRootDir(); - + File rootDir = Util.locateElasticsearchWorkspace(project.getGradle()); gitInfo = objectFactory.property(GitInfo.class).value(factory.provider(() -> GitInfo.gitInfo(rootDir) )); diff --git a/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/util/Util.java b/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/util/Util.java index a939edbde7eb9..5cdc72ebde38e 100644 --- a/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/util/Util.java +++ b/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/util/Util.java @@ -21,6 +21,7 @@ import javax.annotation.Nullable; import java.io.File; +import java.util.Collection; import java.util.Optional; import java.util.function.Supplier; @@ -105,7 +106,6 @@ private static boolean isJavaExtensionAvailable(Project project) { return project.getExtensions().getByType(JavaPluginExtension.class) == null; } - public static Object toStringable(Supplier getter) { return new Object() { @Override @@ -119,21 +119,31 @@ public static SourceSetContainer getJavaSourceSets(Project project) { return project.getExtensions().getByType(JavaPluginExtension.class).getSourceSets(); } - public static File locateElasticsearchWorkspace(Gradle project) { - if (project.getParent() == null) { - // See if any of these included builds is the Elasticsearch project - for (IncludedBuild includedBuild : project.getIncludedBuilds()) { - File versionProperties = new File(includedBuild.getProjectDir(), "build-tools-internal/version.properties"); - if (versionProperties.exists()) { - return includedBuild.getProjectDir(); + public static File locateElasticsearchWorkspace(Gradle gradle) { + if(gradle.getRootProject().getName().startsWith("build-tools")) { + File buildToolsParent = gradle.getRootProject().getRootDir().getParentFile(); + if(versionFileExists(buildToolsParent)) { + return buildToolsParent; } + return buildToolsParent; } + if (gradle.getParent() == null) { + // See if any of these included builds is the Elasticsearch gradle + for (IncludedBuild includedBuild : gradle.getIncludedBuilds()) { + if (versionFileExists(includedBuild.getProjectDir())) { + return includedBuild.getProjectDir(); + } + } - // Otherwise assume this project is the root elasticsearch workspace - return project.getRootProject().getRootDir(); - } else { - // We're an included build, so keep looking - return locateElasticsearchWorkspace(project.getParent()); + // Otherwise assume this gradle is the root elasticsearch workspace + return gradle.getRootProject().getRootDir(); + } else { + // We're an included build, so keep looking + return locateElasticsearchWorkspace(gradle.getParent()); + } } + + private static boolean versionFileExists(File rootDir) { + return new File(rootDir, "build-tools-internal/version.properties").exists(); } } diff --git a/build-tools-internal/build.gradle b/build-tools-internal/build.gradle index a22a76c92dd69..923139673aa9d 100644 --- a/build-tools-internal/build.gradle +++ b/build-tools-internal/build.gradle @@ -107,6 +107,10 @@ gradlePlugin { id = 'elasticsearch.internal-test-rerun' implementationClass = 'org.elasticsearch.gradle.internal.test.rerun.TestRerunPlugin' } + javaToolChainPlugin { + id = 'elasticsearch.java-toolchain' + implementationClass = 'org.elasticsearch.gradle.internal.toolchain.JavaToolChainResolverPlugin' + } javaDoc { id = 'elasticsearch.java-doc' implementationClass = 'org.elasticsearch.gradle.internal.ElasticsearchJavadocPlugin' diff --git a/build-tools-internal/settings.gradle b/build-tools-internal/settings.gradle index 48271149e578e..6423750872ca2 100644 --- a/build-tools-internal/settings.gradle +++ b/build-tools-internal/settings.gradle @@ -1,3 +1,8 @@ +pluginManagement { + includeBuild "../build-conventions" + includeBuild "../build-tools" +} + dependencyResolutionManagement { versionCatalogs { buildLibs { diff --git a/build-tools-internal/src/main/groovy/elasticsearch.ide.gradle b/build-tools-internal/src/main/groovy/elasticsearch.ide.gradle index df21e3d6aa12c..4423af83f98b6 100644 --- a/build-tools-internal/src/main/groovy/elasticsearch.ide.gradle +++ b/build-tools-internal/src/main/groovy/elasticsearch.ide.gradle @@ -245,20 +245,20 @@ Node parseXml(Object path) { return xml } -Pair locateElasticsearchWorkspace(Gradle project) { - if (project.parent == null) { - // See if any of these included builds is the Elasticsearch project - for (IncludedBuild includedBuild : project.includedBuilds) { +Pair locateElasticsearchWorkspace(Gradle gradle) { + if (gradle.parent == null) { + // See if any of these included builds is the Elasticsearch gradle + for (IncludedBuild includedBuild : gradle.includedBuilds) { File versionProperties = new File(includedBuild.projectDir, 'build-tools-internal/version.properties') if (versionProperties.exists()) { return Pair.of(includedBuild.projectDir, includedBuild) } } - // Otherwise assume this project is the root elasticsearch workspace - return Pair.of(project.getRootProject().getRootDir(), null) + // Otherwise assume this gradle is the root elasticsearch workspace + return Pair.of(gradle.getRootProject().getRootDir(), null) } else { // We're an included build, so keep looking - return locateElasticsearchWorkspace(project.parent) + return locateElasticsearchWorkspace(gradle.parent) } } diff --git a/build-tools-internal/src/main/groovy/elasticsearch.runtime-jdk-provision.gradle b/build-tools-internal/src/main/groovy/elasticsearch.runtime-jdk-provision.gradle index 4a35fd9d447da..8d68f77da1e97 100644 --- a/build-tools-internal/src/main/groovy/elasticsearch.runtime-jdk-provision.gradle +++ b/build-tools-internal/src/main/groovy/elasticsearch.runtime-jdk-provision.gradle @@ -35,8 +35,12 @@ configure(allprojects) { test.executable = "${BuildParams.runtimeJavaHome}/bin/java" + (OS.current() == OS.WINDOWS ? '.exe' : '') } else { - test.dependsOn(project.jdks.provisioned_runtime) - test.executable = rootProject.jdks.provisioned_runtime.getBinJavaPath() + test.javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(VersionProperties.bundledJdkMajorVersion) + vendor = VersionProperties.bundledJdkVendor == "openjdk" ? + JvmVendorSpec.ORACLE : + JvmVendorSpec.matching(VersionProperties.bundledJdkVendor) + } } } project.plugins.withId("elasticsearch.testclusters") { testClustersPlugin -> 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 126f0f0e38d62..5aa72c57e4be4 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 @@ -22,6 +22,13 @@ import java.util.Arrays; +/** + * @deprecated We wanna get rid from this and custom jdk downloads via this plugin and + * make leverage the gradle toolchain resolver capabilities. + * + * @See @org.elasticsearch.gradle.internal.toolchain.JavaToolChainResolverPlugin + * */ +@Deprecated public class JdkDownloadPlugin implements Plugin { public static final String VENDOR_ADOPTIUM = "adoptium"; @@ -161,7 +168,6 @@ public static NamedDomainObjectContainer getContainer(Project project) { private static String dependencyNotation(Jdk jdk) { String platformDep = isJdkOnMacOsPlatform(jdk) ? (jdk.getVendor().equals(VENDOR_ADOPTIUM) ? "mac" : "macos") : jdk.getPlatform(); String extension = jdk.getPlatform().equals("windows") ? "zip" : "tar.gz"; - return groupName(jdk) + ":" + platformDep + ":" + jdk.getBaseVersion() + ":" + jdk.getArchitecture() + "@" + extension; } 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 f32b03eaf2877..9cc3e71192d40 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 @@ -20,6 +20,9 @@ import org.gradle.api.Project; import org.gradle.api.logging.Logger; import org.gradle.api.logging.Logging; +import org.gradle.api.model.ObjectFactory; +import org.gradle.api.plugins.JvmToolchainsPlugin; +import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; import org.gradle.api.provider.ProviderFactory; import org.gradle.internal.jvm.Jvm; @@ -27,11 +30,14 @@ import org.gradle.internal.jvm.inspection.JvmMetadataDetector; import org.gradle.internal.jvm.inspection.JvmVendor; import org.gradle.jvm.toolchain.JavaLanguageVersion; +import org.gradle.jvm.toolchain.JavaLauncher; +import org.gradle.jvm.toolchain.JavaToolchainService; import org.gradle.jvm.toolchain.JavaToolchainSpec; import org.gradle.jvm.toolchain.JvmVendorSpec; import org.gradle.jvm.toolchain.internal.InstallationLocation; import org.gradle.jvm.toolchain.internal.JavaInstallationRegistry; import org.gradle.util.GradleVersion; +import org.jetbrains.annotations.NotNull; import java.io.BufferedReader; import java.io.File; @@ -56,19 +62,24 @@ public class GlobalBuildInfoPlugin implements Plugin { private static final Logger LOGGER = Logging.getLogger(GlobalBuildInfoPlugin.class); private static final String DEFAULT_VERSION_JAVA_FILE_PATH = "server/src/main/java/org/elasticsearch/Version.java"; + private ObjectFactory objectFactory; private final JavaInstallationRegistry javaInstallationRegistry; private final JvmMetadataDetector metadataDetector; private final ProviderFactory providers; + private JavaToolchainService toolChainService; @Inject public GlobalBuildInfoPlugin( + ObjectFactory objectFactory, JavaInstallationRegistry javaInstallationRegistry, JvmMetadataDetector metadataDetector, ProviderFactory providers ) { + this.objectFactory = objectFactory; this.javaInstallationRegistry = javaInstallationRegistry; this.metadataDetector = new ErrorTraceMetadataDetector(metadataDetector); this.providers = providers; + } @Override @@ -76,6 +87,8 @@ public void apply(Project project) { if (project != project.getRootProject()) { throw new IllegalStateException(this.getClass().getName() + " can only be applied to the root project."); } + project.getPlugins().apply(JvmToolchainsPlugin.class); + toolChainService = project.getExtensions().getByType(JavaToolchainService.class); GradleVersion minimumGradleVersion = GradleVersion.version(getResourceContents("/minimumGradleVersion")); if (GradleVersion.current().compareTo(minimumGradleVersion) < 0) { throw new GradleException("Gradle " + minimumGradleVersion.getVersion() + "+ is required"); @@ -114,6 +127,8 @@ public void apply(Project project) { params.setTestSeed(getTestSeed()); params.setIsCi(System.getenv("JENKINS_URL") != null || System.getenv("BUILDKITE_BUILD_URL") != null); params.setDefaultParallel(ParallelDetector.findDefaultParallel(project)); + // TODO: Test if cc issues are coming from here + params.setDefaultParallel(8); params.setInFipsJvm(Util.getBooleanProperty("tests.fips.enabled", false)); params.setIsSnapshotBuild(Util.getBooleanProperty("build.snapshot", true)); AtomicReference cache = new AtomicReference<>(); @@ -219,7 +234,7 @@ private InstallationLocation getJavaInstallation(File javaHome) { private boolean isSameFile(File javaHome, InstallationLocation installationLocation) { try { - return Files.isSameFile(installationLocation.getLocation().toPath(), javaHome.toPath()); + return Files.isSameFile(javaHome.toPath(), installationLocation.getLocation().toPath()); } catch (IOException ioException) { throw new UncheckedIOException(ioException); } @@ -294,9 +309,14 @@ private File findRuntimeJavaHome() { } private String findJavaHome(String version) { - Provider javaHomeNames = providers.gradleProperty("org.gradle.java.installations.fromEnv"); String javaHomeEnvVar = getJavaHomeEnvVarName(version); + String env = System.getenv(javaHomeEnvVar); + return env != null ? resolveJavaHomeFromEnvVariable(javaHomeEnvVar) : resolveJavaHomeFromToolChainService(version); + } + @NotNull + private String resolveJavaHomeFromEnvVariable(String javaHomeEnvVar) { + Provider javaHomeNames = providers.gradleProperty("org.gradle.java.installations.fromEnv"); // Provide a useful error if we're looking for a Java home version that we haven't told Gradle about yet Arrays.stream(javaHomeNames.get().split(",")) .filter(s -> s.equals(javaHomeEnvVar)) @@ -309,7 +329,6 @@ private String findJavaHome(String version) { + "updated in gradle.properties file." ) ); - String versionedJavaHome = System.getenv(javaHomeEnvVar); if (versionedJavaHome == null) { final String exceptionMessage = String.format( @@ -320,12 +339,25 @@ private String findJavaHome(String version) { + "it to be picked up. See https://github.com/elastic/elasticsearch/issues/31399 details.", javaHomeEnvVar ); - throw new GradleException(exceptionMessage); } return versionedJavaHome; } + @NotNull + private String resolveJavaHomeFromToolChainService(String version) { + Property value = objectFactory.property(JavaLanguageVersion.class).value(JavaLanguageVersion.of(version)); + Provider javaLauncherProvider = toolChainService.launcherFor( + javaToolchainSpec -> javaToolchainSpec.getLanguageVersion().value(value) + ); + + try { + return javaLauncherProvider.get().getMetadata().getInstallationPath().getAsFile().getCanonicalPath(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + private static String getJavaHomeEnvVarName(String version) { return "JAVA" + version + "_HOME"; } @@ -369,7 +401,7 @@ private static class MetadataBasedToolChainMatcher implements Action (v == null || v.equals(JvmVendorSpec.ADOPTIUM) == false) ? "macos" : "mac"; + case LINUX -> "linux"; + case WINDOWS -> "windows"; + default -> throw new UnsupportedOperationException("Operating system " + operatingSystem); + }; + } + + static String toArchString(Architecture architecture) { + return switch (architecture) { + case X86_64 -> "x64"; + case AARCH64 -> "aarch64"; + case X86 -> "x86"; + }; + } + + protected static boolean anyVendorOr(JvmVendorSpec givenVendor, JvmVendorSpec expectedVendor) { + return givenVendor.matches("any") || givenVendor.equals(expectedVendor); + } +} diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolver.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolver.java new file mode 100644 index 0000000000000..1dd8b0b9d9e2e --- /dev/null +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolver.java @@ -0,0 +1,125 @@ +/* + * 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 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 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 org.apache.commons.compress.utils.Lists; +import org.gradle.jvm.toolchain.JavaLanguageVersion; +import org.gradle.jvm.toolchain.JavaToolchainDownload; +import org.gradle.jvm.toolchain.JavaToolchainRequest; +import org.gradle.jvm.toolchain.JvmVendorSpec; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URI; +import java.net.URL; +import java.util.Comparator; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +import static org.gradle.jvm.toolchain.JavaToolchainDownload.fromUri; + +public abstract class AdoptiumJdkToolchainResolver extends AbstractCustomJavaToolchainResolver { + + // package protected for better testing + final Map> CACHED_SEMVERS = new ConcurrentHashMap<>(); + + @Override + public Optional resolve(JavaToolchainRequest request) { + if (requestIsSupported(request) == false) { + return Optional.empty(); + } + AdoptiumVersionRequest versionRequestKey = toVersionRequest(request); + Optional versionInfo = CACHED_SEMVERS.computeIfAbsent( + versionRequestKey, + (r) -> resolveAvailableVersion(versionRequestKey) + ); + + return versionInfo.map(v -> fromUri(resolveDownloadURI(versionRequestKey, v))); + } + + private AdoptiumVersionRequest toVersionRequest(JavaToolchainRequest request) { + String platform = toOsString(request.getBuildPlatform().getOperatingSystem(), JvmVendorSpec.ADOPTIUM); + String arch = toArchString(request.getBuildPlatform().getArchitecture()); + JavaLanguageVersion javaLanguageVersion = request.getJavaToolchainSpec().getLanguageVersion().get(); + return new AdoptiumVersionRequest(platform, arch, javaLanguageVersion); + } + + private Optional resolveAvailableVersion(AdoptiumVersionRequest requestKey) { + ObjectMapper mapper = new ObjectMapper(); + try { + int languageVersion = requestKey.languageVersion.asInt(); + URL source = new URL( + "https://api.adoptium.net/v3/info/release_versions?architecture=" + + requestKey.arch + + "&image_type=jdk&os=" + + requestKey.platform + + "&project=jdk&release_type=ga" + + "&version=[" + + languageVersion + + "," + + (languageVersion + 1) + + ")" + ); + JsonNode jsonNode = mapper.readTree(source); + JsonNode versionsNode = jsonNode.get("versions"); + return Optional.of( + Lists.newArrayList(versionsNode.iterator()) + .stream() + .map(node -> toVersionInfo(node)) + .sorted(Comparator.comparing(AdoptiumVersionInfo::semver).reversed()) + .findFirst() + .get() + ); + } catch (FileNotFoundException e) { + // request combo not supported (e.g. aarch64 + windows + return Optional.empty(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private AdoptiumVersionInfo toVersionInfo(JsonNode node) { + return new AdoptiumVersionInfo( + node.get("build").asInt(), + node.get("major").asInt(), + node.get("minor").asInt(), + node.get("openjdk_version").asText(), + node.get("security").asInt(), + node.get("semver").asText() + ); + } + + private URI resolveDownloadURI(AdoptiumVersionRequest request, AdoptiumVersionInfo versionInfo) { + return URI.create( + "https://api.adoptium.net/v3/binary/version/jdk-" + + versionInfo.openjdkVersion + + "/" + + request.platform + + "/" + + request.arch + + "/jdk/hotspot/normal/eclipse?project=jdk" + ); + } + + /** + * Check if request can be full-filled by this resolver: + * 1. vendor must be "any" or adoptium + */ + private boolean requestIsSupported(JavaToolchainRequest request) { + return anyVendorOr(request.getJavaToolchainSpec().getVendor().get(), JvmVendorSpec.ADOPTIUM); + } + + record AdoptiumVersionInfo(int build, int major, int minor, String openjdkVersion, int security, String semver) {} + + record AdoptiumVersionRequest(String platform, String arch, JavaLanguageVersion languageVersion) {} +} diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/ArchivedOracleJdkToolchainResolver.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/ArchivedOracleJdkToolchainResolver.java new file mode 100644 index 0000000000000..7965a18408798 --- /dev/null +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/ArchivedOracleJdkToolchainResolver.java @@ -0,0 +1,82 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.gradle.internal.toolchain; + +import org.apache.groovy.util.Maps; +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.platform.Architecture; +import org.gradle.platform.BuildPlatform; +import org.gradle.platform.OperatingSystem; + +import java.net.URI; +import java.util.Map; +import java.util.Optional; + +public abstract class ArchivedOracleJdkToolchainResolver extends AbstractCustomJavaToolchainResolver { + + private static final Map ARCHIVED_BASE_VERSIONS = Maps.of(19, "19.0.2", 18, "18.0.2.1", 17, "17.0.7"); + + @Override + public Optional resolve(JavaToolchainRequest request) { + if (requestIsSupported(request) == false) { + return Optional.empty(); + } + Integer majorVersion = request.getJavaToolchainSpec().getLanguageVersion().get().asInt(); + String baseVersion = ARCHIVED_BASE_VERSIONS.get(majorVersion); + if (baseVersion == null) { + return Optional.empty(); + } + + 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 Optional.of( + () -> URI.create( + "https://download.oracle.com/java/" + + majorVersion + + "/archive/jdk-" + + baseVersion + + "_" + + os + + "-" + + arch + + "_bin." + + extension + ) + ); + } + + /** + * Check if request can be full-filled by this resolver: + * 1. language version not matching bundled jdk version + * 2. vendor must be any or oracle + * 3. Aarch64 windows images are not supported + */ + private boolean requestIsSupported(JavaToolchainRequest request) { + JavaToolchainSpec javaToolchainSpec = request.getJavaToolchainSpec(); + JavaLanguageVersion bundledJdkMajorVersion = JavaLanguageVersion.of(VersionProperties.getBundledJdkMajorVersion()); + if (javaToolchainSpec.getLanguageVersion().get().equals(bundledJdkMajorVersion)) { + return false; + } + if (anyVendorOr(javaToolchainSpec.getVendor().get(), JvmVendorSpec.ORACLE) == false) { + return false; + } + BuildPlatform buildPlatform = request.getBuildPlatform(); + Architecture architecture = buildPlatform.getArchitecture(); + OperatingSystem operatingSystem = buildPlatform.getOperatingSystem(); + return Architecture.AARCH64 != architecture || OperatingSystem.WINDOWS != operatingSystem; + } + +} 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 new file mode 100644 index 0000000000000..c24b23477811e --- /dev/null +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/JavaToolChainResolverPlugin.java @@ -0,0 +1,28 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.gradle.internal.toolchain; + +import org.gradle.api.Plugin; +import org.gradle.api.initialization.Settings; +import org.gradle.jvm.toolchain.JavaToolchainResolverRegistry; + +import javax.inject.Inject; + +public abstract class JavaToolChainResolverPlugin implements Plugin { + @Inject + protected abstract JavaToolchainResolverRegistry getToolchainResolverRegistry(); + + public void apply(Settings settings) { + settings.getPlugins().apply("jvm-toolchain-management"); + JavaToolchainResolverRegistry registry = getToolchainResolverRegistry(); + registry.register(OracleOpenJdkToolchainResolver.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 new file mode 100644 index 0000000000000..e29fdc109a104 --- /dev/null +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolver.java @@ -0,0 +1,99 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.gradle.internal.toolchain; + +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.platform.Architecture; +import org.gradle.platform.BuildPlatform; +import org.gradle.platform.OperatingSystem; + +import java.net.URI; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public abstract class OracleOpenJdkToolchainResolver extends AbstractCustomJavaToolchainResolver { + + private static final Pattern VERSION_PATTERN = Pattern.compile( + "(\\d+)(\\.\\d+\\.\\d+(?:\\.\\d+)?)?\\+(\\d+(?:\\.\\d+)?)(@([a-f0-9]{32}))?" + ); + + // for testing reasons we keep that a package private field + String bundledJdkVersion = VersionProperties.getBundledJdkVersion(); + JavaLanguageVersion bundledJdkMajorVersion = JavaLanguageVersion.of(VersionProperties.getBundledJdkMajorVersion()); + + /** + * We need some place to map JavaLanguageVersion to build, minor version etc. + * */ + @Override + public Optional resolve(JavaToolchainRequest request) { + if (requestIsSupported(request) == false) { + return Optional.empty(); + } + Matcher jdkVersionMatcher = VERSION_PATTERN.matcher(bundledJdkVersion); + if (jdkVersionMatcher.matches() == false) { + throw new IllegalStateException("Unable to parse bundled JDK version " + bundledJdkVersion); + } + String baseVersion = jdkVersionMatcher.group(1) + (jdkVersionMatcher.group(2) != null ? (jdkVersionMatcher.group(2)) : ""); + String build = jdkVersionMatcher.group(3); + String hash = jdkVersionMatcher.group(5); + + 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 Optional.of( + () -> URI.create( + "https://download.oracle.com/java/GA/jdk" + + baseVersion + + "/" + + hash + + "/" + + build + + "/GPL/openjdk-" + + baseVersion + + "_" + + os + + "-" + + arch + + "_bin." + + extension + ) + ); + } + + /** + * Check if request can be full-filled by this resolver: + * 1. BundledJdkVendor should match openjdk + * 2. language version should match bundled jdk version + * 3. vendor must be any or oracle + * 4. Aarch64 windows images are not supported + */ + private boolean requestIsSupported(JavaToolchainRequest request) { + if (VersionProperties.getBundledJdkVendor().toLowerCase().equals("openjdk") == false) { + return false; + } + JavaToolchainSpec javaToolchainSpec = request.getJavaToolchainSpec(); + if (javaToolchainSpec.getLanguageVersion().get().equals(bundledJdkMajorVersion) == false) { + return false; + } + if (anyVendorOr(javaToolchainSpec.getVendor().get(), JvmVendorSpec.ORACLE) == false) { + return false; + } + BuildPlatform buildPlatform = request.getBuildPlatform(); + Architecture architecture = buildPlatform.getArchitecture(); + OperatingSystem operatingSystem = buildPlatform.getOperatingSystem(); + return Architecture.AARCH64 != architecture || OperatingSystem.WINDOWS != operatingSystem; + } +} 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 new file mode 100644 index 0000000000000..de0d969c730dc --- /dev/null +++ b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/AbstractToolchainResolverSpec.groovy @@ -0,0 +1,107 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.gradle.internal.toolchain + +import org.gradle.api.provider.Property +import org.gradle.jvm.toolchain.JavaLanguageVersion +import org.gradle.jvm.toolchain.JavaToolchainDownload +import org.gradle.jvm.toolchain.JavaToolchainRequest +import org.gradle.jvm.toolchain.JavaToolchainResolver +import org.gradle.jvm.toolchain.JavaToolchainSpec +import org.gradle.jvm.toolchain.JvmVendorSpec +import org.gradle.platform.Architecture +import org.gradle.platform.BuildPlatform +import org.gradle.platform.OperatingSystem +import spock.lang.Specification + +import static org.gradle.platform.Architecture.X86_64 +import static org.gradle.platform.OperatingSystem.MAC_OS + +abstract class AbstractToolchainResolverSpec extends Specification { + + def "resolves #os #arch #vendor jdk #langVersion"() { + given: + def resolver = resolverImplementation() + + when: + Optional download = resolver.resolve(request(JavaLanguageVersion.of(langVersion), vendor, platform(os, arch))) + + then: + download.get().uri == URI.create(expectedUrl) + where: + + [langVersion, vendor, os, arch, expectedUrl] << supportedRequests() + } + + + def "does not resolve #os #arch #vendor jdk #langVersion"() { + given: + def resolver = resolverImplementation() + + when: + Optional download = resolver.resolve(request(JavaLanguageVersion.of(langVersion), vendor, platform(os, arch))) + + then: + download.isEmpty() + where: + [langVersion, vendor, os, arch] << unsupportedRequests() + } + + abstract JavaToolchainResolver resolverImplementation(); + + abstract supportedRequests(); + + abstract unsupportedRequests(); + + JavaToolchainRequest request(JavaLanguageVersion languageVersion = null, + JvmVendorSpec vendorSpec = anyVendor(), + BuildPlatform platform = platform()) { + + JavaToolchainSpec toolchainSpec = Mock() + Property languageVersionProperty = Mock() + _ * toolchainSpec.getLanguageVersion() >> languageVersionProperty + _ * languageVersionProperty.get() >> languageVersion + + Property vendorSpecProperty = Mock() + _ * vendorSpecProperty.get() >> vendorSpec + _ * toolchainSpec.getVendor() >> vendorSpecProperty + + JavaToolchainRequest request = Mock() + + _ * request.getJavaToolchainSpec() >> toolchainSpec + _ * request.getBuildPlatform() >> platform + return request + } + + JvmVendorSpec anyVendor() { + return new AnyJvmVendorSpec(); + } + + BuildPlatform platform(OperatingSystem os = MAC_OS, Architecture arch = X86_64) { + return new TestBuildPlatform(operatingSystem: os, architecture: arch) + } + + + static class TestBuildPlatform implements BuildPlatform { + OperatingSystem operatingSystem + Architecture architecture + } + + static class AnyJvmVendorSpec extends JvmVendorSpec { + @Override + boolean matches(String vendor) { + return vendor == "any" + } + + @Override + String toString() { + return "any" + } + } +} 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 new file mode 100644 index 0000000000000..7b8129f8dbaec --- /dev/null +++ b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolverSpec.groovy @@ -0,0 +1,83 @@ +/* + * 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 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 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.platform.OperatingSystem + +import static org.elasticsearch.gradle.internal.toolchain.AbstractCustomJavaToolchainResolver.toArchString +import static org.elasticsearch.gradle.internal.toolchain.AbstractCustomJavaToolchainResolver.toOsString +import static org.gradle.jvm.toolchain.JvmVendorSpec.ADOPTIUM +import static org.gradle.platform.Architecture.AARCH64 +import static org.gradle.platform.Architecture.X86_64 +import static org.gradle.platform.OperatingSystem.LINUX +import static org.gradle.platform.OperatingSystem.MAC_OS +import static org.gradle.platform.OperatingSystem.WINDOWS + +class AdoptiumJdkToolchainResolverSpec extends AbstractToolchainResolverSpec { + + @Override + JavaToolchainResolver resolverImplementation() { + def resolver = new AdoptiumJdkToolchainResolver() { + @Override + BuildServiceParameters.None getParameters() { + return null + } + } + supportedRequests().each { + def languageVersion = JavaLanguageVersion.of(it[0]) + def request = new AdoptiumJdkToolchainResolver.AdoptiumVersionRequest( + toOsString(it[2], it[1]), + toArchString(it[3]), + languageVersion); + resolver.CACHED_SEMVERS.put(request, Optional.of(new AdoptiumJdkToolchainResolver.AdoptiumVersionInfo(languageVersion.asInt(), + 1, + 1, + "" + languageVersion.asInt() + ".1.1.1+37", + 0, "" + languageVersion.asInt() + ".1.1.1" + ))) + + } + return resolver + } + + @Override + def supportedRequests() { + return [ + [19, ADOPTIUM, MAC_OS, X86_64, "https://api.adoptium.net/v3/binary/version/jdk-19.1.1.1+37/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/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/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/mac/aarch64/jdk/hotspot/normal/eclipse?project=jdk"], + [19, ADOPTIUM, LINUX, AARCH64, "https://api.adoptium.net/v3/binary/version/jdk-19.1.1.1+37/linux/aarch64/jdk/hotspot/normal/eclipse?project=jdk"], + + [18, ADOPTIUM, MAC_OS, X86_64, "https://api.adoptium.net/v3/binary/version/jdk-18.1.1.1+37/mac/x64/jdk/hotspot/normal/eclipse?project=jdk"], + [18, ADOPTIUM, LINUX, X86_64, "https://api.adoptium.net/v3/binary/version/jdk-18.1.1.1+37/linux/x64/jdk/hotspot/normal/eclipse?project=jdk"], + [18, ADOPTIUM, WINDOWS, X86_64, "https://api.adoptium.net/v3/binary/version/jdk-18.1.1.1+37/windows/x64/jdk/hotspot/normal/eclipse?project=jdk"], + [18, ADOPTIUM, MAC_OS, AARCH64, "https://api.adoptium.net/v3/binary/version/jdk-18.1.1.1+37/mac/aarch64/jdk/hotspot/normal/eclipse?project=jdk"], + [18, ADOPTIUM, LINUX, AARCH64, "https://api.adoptium.net/v3/binary/version/jdk-18.1.1.1+37/linux/aarch64/jdk/hotspot/normal/eclipse?project=jdk"], + [17, ADOPTIUM, MAC_OS, X86_64, "https://api.adoptium.net/v3/binary/version/jdk-17.1.1.1+37/mac/x64/jdk/hotspot/normal/eclipse?project=jdk"], + [17, ADOPTIUM, LINUX, X86_64, "https://api.adoptium.net/v3/binary/version/jdk-17.1.1.1+37/linux/x64/jdk/hotspot/normal/eclipse?project=jdk"], + [17, ADOPTIUM, WINDOWS, X86_64, "https://api.adoptium.net/v3/binary/version/jdk-17.1.1.1+37/windows/x64/jdk/hotspot/normal/eclipse?project=jdk"], + [17, ADOPTIUM, MAC_OS, AARCH64, "https://api.adoptium.net/v3/binary/version/jdk-17.1.1.1+37/mac/aarch64/jdk/hotspot/normal/eclipse?project=jdk"], + [17, ADOPTIUM, LINUX, AARCH64, "https://api.adoptium.net/v3/binary/version/jdk-17.1.1.1+37/linux/aarch64/jdk/hotspot/normal/eclipse?project=jdk"] + ] + } + + @Override + def unsupportedRequests() { + [ + [19, ADOPTIUM, WINDOWS, AARCH64], + [18, ADOPTIUM, WINDOWS, AARCH64], + [17, ADOPTIUM, WINDOWS, AARCH64] + ] + } + +} diff --git a/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/ArchivedOracleJdkToolchainResolverSpec.groovy b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/ArchivedOracleJdkToolchainResolverSpec.groovy new file mode 100644 index 0000000000000..7ad97480e5f25 --- /dev/null +++ b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/ArchivedOracleJdkToolchainResolverSpec.groovy @@ -0,0 +1,62 @@ +/* + * 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 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 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.JavaToolchainResolver; + +import static org.gradle.jvm.toolchain.JvmVendorSpec.ORACLE +import static org.gradle.platform.Architecture.AARCH64 +import static org.gradle.platform.Architecture.X86_64 +import static org.gradle.platform.OperatingSystem.LINUX +import static org.gradle.platform.OperatingSystem.MAC_OS +import static org.gradle.platform.OperatingSystem.WINDOWS; + +class ArchivedOracleJdkToolchainResolverSpec extends AbstractToolchainResolverSpec { + + @Override + def supportedRequests() { + return [ + [19, ORACLE, MAC_OS, X86_64, "https://download.oracle.com/java/19/archive/jdk-19.0.2_macos-x64_bin.tar.gz"], + [19, ORACLE, MAC_OS, AARCH64, "https://download.oracle.com/java/19/archive/jdk-19.0.2_macos-aarch64_bin.tar.gz"], + [19, ORACLE, LINUX, X86_64, "https://download.oracle.com/java/19/archive/jdk-19.0.2_linux-x64_bin.tar.gz"], + [19, ORACLE, LINUX, AARCH64, "https://download.oracle.com/java/19/archive/jdk-19.0.2_linux-aarch64_bin.tar.gz"], + [19, ORACLE, WINDOWS, X86_64, "https://download.oracle.com/java/19/archive/jdk-19.0.2_windows-x64_bin.zip"], + + [18, ORACLE, MAC_OS, X86_64, "https://download.oracle.com/java/18/archive/jdk-18.0.2.1_macos-x64_bin.tar.gz"], + [18, ORACLE, MAC_OS, AARCH64, "https://download.oracle.com/java/18/archive/jdk-18.0.2.1_macos-aarch64_bin.tar.gz"], + [18, ORACLE, LINUX, X86_64, "https://download.oracle.com/java/18/archive/jdk-18.0.2.1_linux-x64_bin.tar.gz"], + [18, ORACLE, LINUX, AARCH64, "https://download.oracle.com/java/18/archive/jdk-18.0.2.1_linux-aarch64_bin.tar.gz"], + [18, ORACLE, WINDOWS, X86_64, "https://download.oracle.com/java/18/archive/jdk-18.0.2.1_windows-x64_bin.zip"], + + [17, ORACLE, MAC_OS, X86_64, "https://download.oracle.com/java/17/archive/jdk-17.0.7_macos-x64_bin.tar.gz"], + [17, ORACLE, MAC_OS, AARCH64, "https://download.oracle.com/java/17/archive/jdk-17.0.7_macos-aarch64_bin.tar.gz"], + [17, ORACLE, LINUX, X86_64, "https://download.oracle.com/java/17/archive/jdk-17.0.7_linux-x64_bin.tar.gz"], + [17, ORACLE, LINUX, AARCH64, "https://download.oracle.com/java/17/archive/jdk-17.0.7_linux-aarch64_bin.tar.gz"], + [17, ORACLE, WINDOWS, X86_64, "https://download.oracle.com/java/17/archive/jdk-17.0.7_windows-x64_bin.zip"] + ] + } + + def unsupportedRequests() { + [ + [19, ORACLE, WINDOWS, AARCH64], + [18, ORACLE, WINDOWS, AARCH64], + [17, ORACLE, WINDOWS, AARCH64] + ] + } + + JavaToolchainResolver resolverImplementation() { + new ArchivedOracleJdkToolchainResolver() { + @Override + BuildServiceParameters.None getParameters() { + return null + } + } + } +} 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 new file mode 100644 index 0000000000000..b49e734c087cc --- /dev/null +++ b/build-tools-internal/src/test/groovy/org/elasticsearch/gradle/internal/toolchain/OracleOpenJdkToolchainResolverSpec.groovy @@ -0,0 +1,51 @@ +/* + * 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 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 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 static org.gradle.jvm.toolchain.JvmVendorSpec.ORACLE +import static org.gradle.platform.Architecture.* +import static org.gradle.platform.OperatingSystem.* + +class OracleOpenJdkToolchainResolverSpec extends AbstractToolchainResolverSpec { + + OracleOpenJdkToolchainResolver resolverImplementation() { + var toolChain = new OracleOpenJdkToolchainResolver() { + @Override + BuildServiceParameters.None getParameters() { + return null + } + } + toolChain.bundledJdkVersion = "20+36@bdc68b4b9cbc4ebcb30745c85038d91d" + toolChain.bundledJdkMajorVersion = JavaLanguageVersion.of(20) + toolChain + } + + def supportedRequests() { + [[20, ORACLE, MAC_OS, X86_64, "https://download.oracle.com/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_macos-x64_bin.tar.gz"], + [20, ORACLE, MAC_OS, AARCH64, "https://download.oracle.com/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_macos-aarch64_bin.tar.gz"], + [20, ORACLE, LINUX, X86_64, "https://download.oracle.com/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_linux-x64_bin.tar.gz"], + [20, ORACLE, LINUX, AARCH64, "https://download.oracle.com/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_linux-aarch64_bin.tar.gz"], + [20, ORACLE, WINDOWS, X86_64, "https://download.oracle.com/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_windows-x64_bin.zip"], + [20, anyVendor(), MAC_OS, X86_64, "https://download.oracle.com/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_macos-x64_bin.tar.gz"], + [20, anyVendor(), MAC_OS, AARCH64, "https://download.oracle.com/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_macos-aarch64_bin.tar.gz"], + [20, anyVendor(), LINUX, X86_64, "https://download.oracle.com/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_linux-x64_bin.tar.gz"], + [20, anyVendor(), LINUX, AARCH64, "https://download.oracle.com/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_linux-aarch64_bin.tar.gz"], + [20, anyVendor(), WINDOWS, X86_64, "https://download.oracle.com/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_windows-x64_bin.zip"]] + } + + def unsupportedRequests() { + [ + [20, ORACLE, WINDOWS, AARCH64] + ] + } + +} diff --git a/build-tools/settings.gradle b/build-tools/settings.gradle index 4c7fb225b12a1..63d80efcd505e 100644 --- a/build-tools/settings.gradle +++ b/build-tools/settings.gradle @@ -5,6 +5,10 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ +pluginManagement { + includeBuild "../build-conventions" +} + include 'reaper' dependencyResolutionManagement { diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/VersionProperties.java b/build-tools/src/main/java/org/elasticsearch/gradle/VersionProperties.java index 895d0c60198e0..c4312d113ffd8 100644 --- a/build-tools/src/main/java/org/elasticsearch/gradle/VersionProperties.java +++ b/build-tools/src/main/java/org/elasticsearch/gradle/VersionProperties.java @@ -30,6 +30,10 @@ public static String getLucene() { return lucene; } + public static String getBundledJdkMajorVersion() { + return bundledJdkMajorVersion; + } + public static String getBundledJdkVersion() { return bundledJdkVersion; } @@ -45,7 +49,9 @@ public static Map getVersions() { private static final String elasticsearch; private static final String lucene; private static final String bundledJdkVersion; + private static final String bundledJdkMajorVersion; private static final String bundledJdkVendor; + private static final Map versions = new HashMap(); static { @@ -54,6 +60,7 @@ public static Map getVersions() { lucene = props.getProperty("lucene"); bundledJdkVendor = props.getProperty("bundled_jdk_vendor"); bundledJdkVersion = props.getProperty("bundled_jdk"); + bundledJdkMajorVersion = bundledJdkVersion.split("[.+]")[0]; for (String property : props.stringPropertyNames()) { versions.put(property, props.getProperty(property)); diff --git a/build.gradle b/build.gradle index d03398bb48e6e..734d5d607134f 100644 --- a/build.gradle +++ b/build.gradle @@ -19,8 +19,6 @@ import org.elasticsearch.gradle.internal.info.BuildParams import org.elasticsearch.gradle.util.GradleUtils import org.gradle.plugins.ide.eclipse.model.AccessRule import org.gradle.plugins.ide.eclipse.model.ProjectDependency -import org.gradle.util.internal.DistributionLocator -import org.gradle.util.GradleVersion import java.nio.file.Files diff --git a/settings.gradle b/settings.gradle index df9beda6f0002..794bf9a28f2b9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,18 +1,23 @@ +import org.elasticsearch.gradle.internal.toolchain.OracleOpenJdkToolchainResolver +import org.elasticsearch.gradle.internal.toolchain.ArchivedOracleJdkToolchainResolver +import org.elasticsearch.gradle.internal.toolchain.AdoptiumJdkToolchainResolver + pluginManagement { repositories { mavenCentral() gradlePluginPortal() } + + includeBuild "build-conventions" + includeBuild "build-tools" + includeBuild "build-tools-internal" } plugins { id "com.gradle.enterprise" version "3.12.6" + id 'elasticsearch.java-toolchain' } -includeBuild "build-conventions" -includeBuild "build-tools" -includeBuild "build-tools-internal" - rootProject.name = "elasticsearch" dependencyResolutionManagement { @@ -23,6 +28,22 @@ dependencyResolutionManagement { } } +toolchainManagement { + jvm { + javaRepositories { + repository('bundledOracleOpendJdk') { + resolverClass = OracleOpenJdkToolchainResolver + } + repository('adoptiumJdks') { + resolverClass = AdoptiumJdkToolchainResolver + } + repository('archivedOracleJdks') { + resolverClass = ArchivedOracleJdkToolchainResolver + } + } + } +} + List projects = [ 'rest-api-spec', 'docs', diff --git a/test/test-clusters/build.gradle b/test/test-clusters/build.gradle index fa940e9769816..f24416023edb1 100644 --- a/test/test-clusters/build.gradle +++ b/test/test-clusters/build.gradle @@ -14,5 +14,5 @@ dependencies { } tasks.named("processResources").configure { - from(new File(Util.locateElasticsearchWorkspace(gradle), "build-tools-internal/version.properties")) + from(new File(Util.locateElasticsearchWorkspace(project.gradle), "build-tools-internal/version.properties")) }