66464: junitlauncher task's fork element now has a new optional "java" attribute to allow specifying a different Java installation to run the forked tests
diff --git a/WHATSNEW b/WHATSNEW
index 216d69c..cd2d2bc 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -18,6 +18,14 @@
    This is now fixed.
    Bugzilla Report 66468
 
+Other changes:
+--------------
+
+ * <fork> element of the junitlauncher task now has a new optional "java"
+   attribute which can be used to point to a different Java installation
+   for runnning the forked tests.
+   Bugzilla Report 66464
+
 Changes from Ant 1.10.12 TO Ant 1.10.13
 =======================================
 
diff --git a/manual/Tasks/junitlauncher.html b/manual/Tasks/junitlauncher.html
index 0f20648..acecddd 100644
--- a/manual/Tasks/junitlauncher.html
+++ b/manual/Tasks/junitlauncher.html
@@ -631,6 +631,15 @@
             JVM, is expected to contain the Ant runtime jars</td>
         <td>No. Value defaults to <code>true</code>.</td>
     </tr>
+    <tr>
+        <td>java</td>
+        <td>The command used to launch the forked <code>java</code> process. This attribute can be set
+        to point to a different installation of Java than the one that is currently being used to
+        run the Ant build
+            <p><em>Since Ant 1.10.14</em></p>
+        </td>
+        <td>No</td>
+    </tr>
 </table>
 
 The <code>fork</code> element allows the following nested elements:
diff --git a/src/etc/testcases/taskdefs/optional/junitlauncher.xml b/src/etc/testcases/taskdefs/optional/junitlauncher.xml
index 87b00ad..1163dc2 100644
--- a/src/etc/testcases/taskdefs/optional/junitlauncher.xml
+++ b/src/etc/testcases/taskdefs/optional/junitlauncher.xml
@@ -371,5 +371,32 @@
             <listener type="legacy-brief" sendSysOut="true" useLegacyReportingName="true"/>
         </junitlauncher>
     </target>
+
+    <target name="test-fork-different-java" depends="init">
+        <!-- create a symlinked file which points to the "java" command
+        and use that symlink to launch the forked JVM -->
+        <property name="different-java" value="${java.io.tmpdir}/foobarjava"/>
+        <delete file="${different-java}"/>
+        <symlink resource="${java.home}/bin/java" link="${different-java}"/>
+
+        <junitlauncher>
+            <classpath refid="test.classpath"/>
+            <test name="org.example.junitlauncher.vintage.ForkedTest" outputdir="${output.dir}">
+                <listener classname="org.example.junitlauncher.Tracker"
+                          outputDir="${output.dir}"
+                          resultFile="${test-fork-different-java.tracker}"
+                          if="test-fork-different-java.tracker"/>
+
+                <!-- we just verify that the launch of the forked JVM works fine and the test
+                succeeds. There isn't a (easy) way we can actually verify the binary that was used
+                to launch the forked JVM -->
+                <fork dir="${basedir}" java="${different-java}">
+                    <sysproperty key="junitlauncher.test.sysprop.one" value="forked"/>
+                </fork>
+
+                <listener type="legacy-xml"/>
+            </test>
+        </junitlauncher>
+    </target>
 </project>
 
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/confined/ForkDefinition.java b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/confined/ForkDefinition.java
index cfa01d4..c8a40c6 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/confined/ForkDefinition.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/confined/ForkDefinition.java
@@ -102,6 +102,17 @@
     }
 
     /**
+     * The command used to launch {@code java}. This can be a path to the {@code java}
+     * binary that will be used to launch the forked {@code java} process.
+     *
+     * @param java Path to the java command
+     * @since Ant 1.10.14
+     */
+    public void setJava(String java) {
+        this.commandLineJava.setVm(java);
+    }
+
+    /**
      * Generates a new {@link CommandlineJava} constructed out of the configurations set on this
      * {@link ForkDefinition}
      *
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTaskTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTaskTest.java
index 1c36672..f3938d4 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTaskTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTaskTest.java
@@ -22,6 +22,7 @@
 import static org.example.junitlauncher.Tracker.verifySkipped;
 import static org.example.junitlauncher.Tracker.verifySuccess;
 import static org.example.junitlauncher.Tracker.wasTestRun;
+import static org.junit.Assume.assumeTrue;
 
 import java.io.File;
 import java.io.IOException;
@@ -33,6 +34,7 @@
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.BuildFileRule;
 import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.Os;
 import org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.JUnitLauncherTask;
 import org.apache.tools.ant.util.LoaderUtils;
 import org.example.junitlauncher.jupiter.JupiterSampleTest;
@@ -480,6 +482,22 @@
                 ForkedTest.class.getName(), "testSysProp"));
     }
 
+    /**
+     * Tests that tests launched by the junitlauncher task can use a different "java" command
+     * to launch the forked JVM
+     */
+    @Test
+    public void testForkDifferentJava() throws Exception {
+        // the target uses symlink, so we first make sure symlink is available on this system
+        assumeTrue("Symlinks not supported on current operating system", Os.isFamily("unix"));
+        final String targetName = "test-fork-different-java";
+        final Path trackerFile = setupTrackerProperty(targetName);
+        buildRule.executeTarget(targetName);
+
+        Assert.assertTrue("ForkedTest#testSysProp was expected to succeed", verifySuccess(trackerFile,
+                ForkedTest.class.getName(), "testSysProp"));
+    }
+
     private Path setupTrackerProperty(final String targetName) {
         final String filename = targetName + "-tracker.txt";
         buildRule.getProject().setProperty(targetName + ".tracker", filename);