Browse Source

Allow easing testing of java ea versions using gradle java tool chain support (#88188)

This introduces the ability to simply configure a java tool chain for elasticsearch java projects to be used.
If an environment variable `JAVA_TOOLCHAIN_HOME `is declared, this JDK will be used as toolChain in elasticsearch.java projects. If JAVA_RUNTIME_HOME is configured, it takes precedence over JAVA_TOOLCHAIN_HOME
for configuring test cluster runtimes.

This should make testing our build with java `ea` versions easier and allows detangling the used compiler jdk from the gradle java runtime.
Rene Groeschke 3 years ago
parent
commit
90fe732024

+ 3 - 2
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/ElasticsearchJavaBasePlugin.java

@@ -106,11 +106,12 @@ public class ElasticsearchJavaBasePlugin implements Plugin<Project> {
      */
     public static void configureCompile(Project project) {
         project.getExtensions().getExtraProperties().set("compactProfile", "full");
-
         JavaPluginExtension java = project.getExtensions().getByType(JavaPluginExtension.class);
+        if (BuildParams.getJavaToolChainSpec().isPresent()) {
+            java.toolchain(BuildParams.getJavaToolChainSpec().get());
+        }
         java.setSourceCompatibility(BuildParams.getMinimumRuntimeVersion());
         java.setTargetCompatibility(BuildParams.getMinimumRuntimeVersion());
-
         project.getTasks().withType(JavaCompile.class).configureEach(compileTask -> {
             CompileOptions compileOptions = compileTask.getOptions();
             /*

+ 11 - 0
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/BuildParams.java

@@ -8,8 +8,10 @@
 package org.elasticsearch.gradle.internal.info;
 
 import org.elasticsearch.gradle.internal.BwcVersions;
+import org.gradle.api.Action;
 import org.gradle.api.JavaVersion;
 import org.gradle.api.provider.Provider;
+import org.gradle.jvm.toolchain.JavaToolchainSpec;
 
 import java.io.File;
 import java.lang.reflect.Modifier;
@@ -28,6 +30,7 @@ public class BuildParams {
     private static JavaVersion minimumRuntimeVersion;
     private static JavaVersion gradleJavaVersion;
     private static JavaVersion runtimeJavaVersion;
+    private static Provider<? extends Action<JavaToolchainSpec>> javaToolChainSpec;
     private static String runtimeJavaDetails;
     private static Boolean inFipsJvm;
     private static String gitRevision;
@@ -119,6 +122,10 @@ public class BuildParams {
         return value(BuildParams.isSnapshotBuild);
     }
 
+    public static Provider<? extends Action<JavaToolchainSpec>> getJavaToolChainSpec() {
+        return javaToolChainSpec;
+    }
+
     private static <T> T value(T object) {
         if (object == null) {
             String callingMethod = Thread.currentThread().getStackTrace()[2].getMethodName();
@@ -227,5 +234,9 @@ public class BuildParams {
         public void setBwcVersions(Provider<BwcVersions> bwcVersions) {
             BuildParams.bwcVersions = requireNonNull(bwcVersions);
         }
+
+        public void setJavaToolChainSpec(Provider<? extends Action<JavaToolchainSpec>> javaToolChain) {
+            BuildParams.javaToolChainSpec = javaToolChain;
+        }
     }
 }

+ 45 - 4
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java

@@ -12,6 +12,7 @@ import org.elasticsearch.gradle.internal.BwcVersions;
 import org.elasticsearch.gradle.internal.conventions.info.GitInfo;
 import org.elasticsearch.gradle.internal.conventions.info.ParallelDetector;
 import org.elasticsearch.gradle.internal.conventions.util.Util;
+import org.gradle.api.Action;
 import org.gradle.api.GradleException;
 import org.gradle.api.JavaVersion;
 import org.gradle.api.Plugin;
@@ -24,6 +25,9 @@ import org.gradle.internal.jvm.Jvm;
 import org.gradle.internal.jvm.inspection.JvmInstallationMetadata;
 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.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;
@@ -88,12 +92,12 @@ public class GlobalBuildInfoPlugin implements Plugin<Project> {
         BuildParams.init(params -> {
             params.reset();
             params.setRuntimeJavaHome(runtimeJavaHome);
-            // TODO: Temporarily hard-code this to 17 until we upgrade to Gradle 7.3 and bump minimumRuntimeVersion
+            params.setJavaToolChainSpec(resolveToolchainSpecFromEnv());
             params.setRuntimeJavaVersion(
                 determineJavaVersion(
                     "runtime java.home",
                     runtimeJavaHome,
-                    isRuntimeJavaHomeSet ? JavaVersion.VERSION_17 : Jvm.current().getJavaVersion()
+                    isRuntimeJavaHomeSet ? minimumRuntimeVersion : Jvm.current().getJavaVersion()
                 )
             );
             params.setIsRuntimeJavaHomeSet(isRuntimeJavaHomeSet);
@@ -122,6 +126,19 @@ public class GlobalBuildInfoPlugin implements Plugin<Project> {
         project.getGradle().getTaskGraph().whenReady(graph -> logGlobalBuildInfo());
     }
 
+    private Provider<MetadataBasedToolChainMatcher> resolveToolchainSpecFromEnv() {
+        return providers.environmentVariable("JAVA_TOOLCHAIN_HOME").map(toolChainEnvVariable -> {
+            File toolChainDir = new File(toolChainEnvVariable);
+            JvmInstallationMetadata metadata = metadataDetector.getMetadata(toolChainDir);
+            if (metadata.isValidInstallation() == false) {
+                throw new GradleException(
+                    "Configured JAVA_TOOLCHAIN_HOME " + toolChainEnvVariable + " does not point to a valid jdk installation."
+                );
+            }
+            return new MetadataBasedToolChainMatcher(metadata);
+        });
+    }
+
     private String formatJavaVendorDetails(JvmInstallationMetadata runtimeJdkMetaData) {
         JvmVendor vendor = runtimeJdkMetaData.getVendor();
         return runtimeJdkMetaData.getVendor().getKnownVendor().name() + "/" + vendor.getRawVendor();
@@ -166,6 +183,10 @@ public class GlobalBuildInfoPlugin implements Plugin<Project> {
             LOGGER.quiet("  JDK Version           : " + gradleJvmImplementationVersion + " (" + gradleJvmVendorDetails + ")");
             LOGGER.quiet("  JAVA_HOME             : " + gradleJvm.getJavaHome());
         }
+        String javaToolchainHome = System.getenv("JAVA_TOOLCHAIN_HOME");
+        if (javaToolchainHome != null) {
+            LOGGER.quiet("  JAVA_TOOLCHAIN_HOME   : " + javaToolchainHome);
+        }
         LOGGER.quiet("  Random Testing Seed   : " + BuildParams.getTestSeed());
         LOGGER.quiet("  In FIPS 140 mode      : " + BuildParams.isInFipsJvm());
         LOGGER.quiet("=======================================");
@@ -260,8 +281,13 @@ public class GlobalBuildInfoPlugin implements Plugin<Project> {
         if (runtimeJavaProperty != null) {
             return new File(findJavaHome(runtimeJavaProperty));
         }
-
-        return System.getenv("RUNTIME_JAVA_HOME") == null ? Jvm.current().getJavaHome() : new File(System.getenv("RUNTIME_JAVA_HOME"));
+        String env = System.getenv("RUNTIME_JAVA_HOME");
+        if (env != null) {
+            return new File(env);
+        }
+        // fall back to tool chain if set.
+        env = System.getenv("JAVA_TOOLCHAIN_HOME");
+        return env == null ? Jvm.current().getJavaHome() : new File(env);
     }
 
     private String findJavaHome(String version) {
@@ -336,4 +362,19 @@ public class GlobalBuildInfoPlugin implements Plugin<Project> {
         }
     }
 
+    private static class MetadataBasedToolChainMatcher implements Action<JavaToolchainSpec> {
+        private final JvmVendorSpec expectedVendorSpec;
+        private final JavaLanguageVersion expectedJavaLanguageVersion;
+
+        public MetadataBasedToolChainMatcher(JvmInstallationMetadata metadata) {
+            expectedVendorSpec = JvmVendorSpec.matching(metadata.getVendor().getRawVendor());
+            expectedJavaLanguageVersion = JavaLanguageVersion.of(metadata.getLanguageVersion().getMajorVersion());
+        }
+
+        @Override
+        public void execute(JavaToolchainSpec spec) {
+            spec.getVendor().set(expectedVendorSpec);
+            spec.getLanguageVersion().set(expectedJavaLanguageVersion);
+        }
+    }
 }

+ 1 - 1
gradle.properties

@@ -16,4 +16,4 @@ systemProp.jdk.tls.client.protocols=TLSv1.2
 
 # java homes resolved by environment variables
 org.gradle.java.installations.auto-detect=false
-org.gradle.java.installations.fromEnv=JAVA_HOME,RUNTIME_JAVA_HOME,JAVA19_HOME,JAVA18_HOME,JAVA17_HOME,JAVA16_HOME,JAVA15_HOME,JAVA14_HOME,JAVA13_HOME,JAVA12_HOME,JAVA11_HOME,JAVA8_HOME
+org.gradle.java.installations.fromEnv=JAVA_TOOLCHAIN_HOME,JAVA_HOME,RUNTIME_JAVA_HOME,JAVA19_HOME,JAVA18_HOME,JAVA17_HOME,JAVA16_HOME,JAVA15_HOME,JAVA14_HOME,JAVA13_HOME,JAVA12_HOME,JAVA11_HOME,JAVA8_HOME