LUCENE-9312: Allow builds against arbitrary JVMs (squashed
jira/LUCENE-9312)
diff --git a/build.gradle b/build.gradle
index 668c345..a38ca1f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -94,7 +94,7 @@
 apply from: file('gradle/testing/defaults-tests.gradle')
 apply from: file('gradle/testing/randomization.gradle')
 apply from: file('gradle/testing/fail-on-no-tests.gradle')
-apply from: file('gradle/testing/runtime-jvm-support.gradle')
+apply from: file('gradle/testing/alternative-jdk-support.gradle')
 apply from: file('gradle/jar-manifest.gradle')
 
 // Maven publishing.
@@ -149,6 +149,6 @@
 apply from: file('gradle/documentation/documentation.gradle')
 apply from: file('gradle/documentation/changes-to-html.gradle')
 apply from: file('gradle/documentation/markdown.gradle')
-apply from: file('gradle/render-javadoc.gradle')
+apply from: file('gradle/documentation/render-javadoc.gradle')
 
 apply from: file('gradle/hacks/findbugs.gradle')
diff --git a/gradle/render-javadoc.gradle b/gradle/documentation/render-javadoc.gradle
similarity index 95%
rename from gradle/render-javadoc.gradle
rename to gradle/documentation/render-javadoc.gradle
index 7fcee58..27d282b 100644
--- a/gradle/render-javadoc.gradle
+++ b/gradle/documentation/render-javadoc.gradle
@@ -1,3 +1,5 @@
+import javax.annotation.Nullable
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -150,6 +152,11 @@
 
   @Input
   def solrDocUrl = "${->project.solrDocUrl}"
+
+  @Nullable
+  @Optional
+  @Input
+  def executable
   
   /** Utility method to recursively collect all tasks with same name like this one that we depend on */
   private Set findRenderTasksInDependencies() {
@@ -165,8 +172,6 @@
 
   @TaskAction
   public void render() {
-    def javadocCmd = org.gradle.internal.jvm.Jvm.current().getJavadocExecutable()
-
     def srcDirs = srcDirSet.srcDirs.findAll { dir -> dir.exists() }
     def optionsFile = project.file("${getTemporaryDir()}/javadoc-options.txt")
     
@@ -254,6 +259,18 @@
       }
     })
 
+    def javadocCmd = {
+      if (executable == null) {
+        JavaInstallationRegistry registry = project.extensions.getByType(JavaInstallationRegistry)
+        JavaInstallation currentJvm = registry.installationForCurrentVirtualMachine.get()
+        return currentJvm.jdk.get().javadocExecutable.asFile
+      } else {
+        return project.file(executable)
+      }
+    }()
+
+    logger.info("Javadoc executable used: ${javadocCmd}")
+
     def outputFile = project.file("${getTemporaryDir()}/javadoc-output.txt")
     def result
     outputFile.withOutputStream { output ->
diff --git a/gradle/help.gradle b/gradle/help.gradle
index d76ce90..edee1c3 100644
--- a/gradle/help.gradle
+++ b/gradle/help.gradle
@@ -22,6 +22,7 @@
       ["Workflow", "help/workflow.txt", "Typical workflow commands."],
       ["Ant", "help/ant.txt", "Ant-gradle migration help."],
       ["Tests", "help/tests.txt", "Tests, filtering, beasting, etc."],
+      ["Jvms", "help/jvms.txt", "Using alternative or EA JVM toolchains."],
       ["Deps", "help/dependencies.txt", "Declaring, inspecting and excluding dependencies."],
       ["ForbiddenApis", "help/forbiddenApis.txt", "How to add/apply rules for forbidden APIs."],
       ["LocalSettings", "help/localSettings.txt", "Local settings, overrides and build performance tweaks."],
diff --git a/gradle/testing/alternative-jdk-support.gradle b/gradle/testing/alternative-jdk-support.gradle
new file mode 100644
index 0000000..1e69291
--- /dev/null
+++ b/gradle/testing/alternative-jdk-support.gradle
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This adds support for compiling and testing against a different Java runtime.
+// This is the only way to build against JVMs not yet supported by Gradle itself.
+
+JavaInstallationRegistry registry = extensions.getByType(JavaInstallationRegistry)
+
+JavaInstallation currentJvm = registry.installationForCurrentVirtualMachine.get()
+
+JavaInstallation altJvm = {
+  def runtimeJavaHome = propertyOrDefault("runtime.java.home", System.getenv('RUNTIME_JAVA_HOME'))
+  if (!runtimeJavaHome) {
+    return currentJvm
+  } else {
+    return registry.installationForDirectory(
+        layout.projectDirectory.dir(runtimeJavaHome)).get()
+  }
+}()
+
+if (!currentJvm.javaExecutable.equals(altJvm.javaExecutable)) {
+  // Set up java toolchain tasks to use the alternative Java.
+  // This is a related Gradle issue for the future:
+  // https://github.com/gradle/gradle/issues/1652
+
+  configure(rootProject) {
+    task altJvmWarning() {
+      doFirst {
+        logger.warn("""NOTE: Alternative java toolchain will be used for compilation and tests:
+  Project will use Java ${altJvm.javaVersion} from: ${altJvm.installationDirectory}
+  Gradle runs with Java ${currentJvm.javaVersion} from: ${currentJvm.installationDirectory}
+""")
+      }
+    }
+  }
+
+  // Set up toolchain-dependent tasks to use the alternative JVM.
+  allprojects {
+    // Any tests
+    tasks.withType(Test) {
+      dependsOn ":altJvmWarning"
+      executable = altJvm.javaExecutable
+    }
+
+    // Any javac compilation tasks
+    tasks.withType(JavaCompile) {
+      dependsOn ":altJvmWarning"
+      options.fork = true
+      options.forkOptions.javaHome = altJvm.installationDirectory.asFile
+    }
+
+    def javadocExecutable = altJvm.jdk.get().javadocExecutable.asFile
+    tasks.matching { it.name == "renderJavadoc" || it.name == "renderSiteJavadoc" }.all {
+      dependsOn ":altJvmWarning"
+      executable = javadocExecutable
+    }
+  }
+}
diff --git a/gradle/testing/runtime-jvm-support.gradle b/gradle/testing/runtime-jvm-support.gradle
deleted file mode 100644
index ce48b56..0000000
--- a/gradle/testing/runtime-jvm-support.gradle
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// This adds support for compiling and testing against a different Java runtime.
-// This is the only way to build against JVMs not yet supported by Gradle itself.
-
-import org.gradle.internal.jvm.Jvm
-
-def jvmForTests = {
-  def runtimeJavaHome = propertyOrDefault("runtime.java.home", System.getenv('RUNTIME_JAVA_HOME'))
-  if (!runtimeJavaHome) {
-    return Jvm.current()
-  } else {
-    return Jvm.forHome(file(runtimeJavaHome))
-  }
-}()
-def jvmGradle = Jvm.current()
-
-def differentTestJvm = (jvmGradle.javaHome.canonicalPath != jvmForTests.javaHome.canonicalPath)
-
-// Set up tasks to use the alternative Java.
-if (differentTestJvm) {
-  configure(rootProject) {
-    task testJvmWarning() {
-      doFirst {
-        logger.warn("This Java will be used for running tests: ${jvmForTests.javaExecutable}")
-      }
-    }
-  }
-
-  // Set up test tasks to use the alternative JVM.
-  allprojects {
-    tasks.withType(Test) {
-      dependsOn ":testJvmWarning"
-      executable = jvmForTests.javaExecutable
-    }
-  }
-}
\ No newline at end of file
diff --git a/help/jvms.txt b/help/jvms.txt
new file mode 100644
index 0000000..42a88d2
--- /dev/null
+++ b/help/jvms.txt
@@ -0,0 +1,18 @@
+Compiling and testing against different JVMs
+============================================
+
+By default tests are executed with the same Java Gradle is using internally.
+
+To run tests against a different Java version, define a property called
+"runtime.java.home" or define an environment variable "RUNTIME_JAVA_HOME"
+pointing at the JDK installation folder.
+
+If property is being used, it can be a system property (-D...) or a project
+property (-P...).
+
+Example:
+
+gradlew test -p lucene/test-framework --tests TestJvmInfo -Dtests.verbose=true -Druntime.java.home=/jvms/jdk14
+
+Note that an alternative JVM can also be made the "default" setting
+by adding it to (project-local) gradle.properties.
diff --git a/help/tests.txt b/help/tests.txt
index 2caef22..30b1f4a 100644
--- a/help/tests.txt
+++ b/help/tests.txt
@@ -140,18 +140,3 @@
 to increase the top-N count:
 
 gradlew -p lucene/core test -Ptests.profile=true -Ptests.profile.count=100
-
-Testing against different JVMs
-------------------------------
-
-By default tests are executed with the same Java gradle is using internally.
-To run tests against a different Java version define a property called
-"runtime.java.home" or define an environment variable "RUNTIME_JAVA_HOME"
-pointing at the JDK installation folder.
-
-If property is used, it can be a system property (-D...) or a project
-property (-P...).
-
-Example:
-
-gradlew test -p lucene/test-framework --tests TestJvmInfo -Dtests.verbose=true -Druntime.java.home=/jvms/jdk14
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 119a37d..ea17066 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -134,6 +134,8 @@
 
 Other
 
+* LUCENE-9312: Allow gradle builds against arbitrary JVMs. (Tomoko Uchida, Dawid Weiss)
+
 * LUCENE-9391: Upgrade HPPC to 0.8.2. (Haoyu Zhai)
 
 * LUCENE-8768: Fix Javadocs build in Java 11. (Namgyu Kim)