Only enable support for tests.profile if jdk.jfr module is available in Gradle runtime (#12845)

diff --git a/build.gradle b/build.gradle
index f396a77..5196488 100644
--- a/build.gradle
+++ b/build.gradle
@@ -111,6 +111,9 @@
 
 apply from: file('gradle/generation/local-settings.gradle')
 
+// Make sure the build environment is consistent.
+apply from: file('gradle/validation/check-environment.gradle')
+
 // IDE support, settings and specials.
 apply from: file('gradle/ide/intellij-idea.gradle')
 apply from: file('gradle/ide/eclipse.gradle')
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index b946105..9879caa 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -38,3 +38,9 @@
   implementation "commons-codec:commons-codec:${scriptDepVersions['commons-codec']}"
 }
 
+if (!rootProject.hasJavaFlightRecorder) {
+  logger.warn('Module jdk.jfr is not available; skipping compilation of Java Flight Recorder support.')
+  tasks.named('compileJava').configure {
+    exclude('**/ProfileResults.java')
+  }
+}
diff --git a/gradle/testing/profiling.gradle b/gradle/testing/profiling.gradle
index 34b3efe..6c71b3f 100644
--- a/gradle/testing/profiling.gradle
+++ b/gradle/testing/profiling.gradle
@@ -15,20 +15,18 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.gradle.ProfileResults;
-
 def recordings = files()
 
 allprojects {
   plugins.withType(JavaPlugin) {
     ext {
       testOptions += [
-          [propName: 'tests.profile', value: false, description: "Enable java flight recorder profiling."]
+          [propName: 'tests.profile', value: false, description: "Enable Java Flight Recorder profiling."]
       ]
     }
 
     if (resolvedTestOption("tests.profile").toBoolean()) {
-      allprojects {
+      if (rootProject.hasJavaFlightRecorder) {
         tasks.withType(Test) {
           jvmArgs("-XX:StartFlightRecording=dumponexit=true,maxsize=250M,settings=" + rootProject.file("gradle/testing/profiling.jfc"),
               "-XX:+UnlockDiagnosticVMOptions",
@@ -41,6 +39,8 @@
             recordings = recordings.plus fileTree(dir: workingDir, include: '*.jfr')
           }
         }
+      } else {
+        throw new GradleException('Module jdk.jfr is not available; Java Flight Recorder profiles cannot be enabled.')
       }
     }
   }
@@ -48,10 +48,11 @@
 
 gradle.buildFinished {
   if (!recordings.isEmpty()) {
-    ProfileResults.printReport(recordings.getFiles().collect { it.toString() },
-        propertyOrDefault(ProfileResults.MODE_KEY, ProfileResults.MODE_DEFAULT) as String,
-        Integer.parseInt(propertyOrDefault(ProfileResults.STACKSIZE_KEY, ProfileResults.STACKSIZE_DEFAULT)),
-        Integer.parseInt(propertyOrDefault(ProfileResults.COUNT_KEY, ProfileResults.COUNT_DEFAULT)),
-        Boolean.parseBoolean(propertyOrDefault(ProfileResults.LINENUMBERS_KEY, ProfileResults.LINENUMBERS_DEFAULT)))
+    def pr = org.apache.lucene.gradle.ProfileResults;
+    pr.printReport(recordings.getFiles().collect { it.toString() },
+        propertyOrDefault(pr.MODE_KEY, pr.MODE_DEFAULT) as String,
+        Integer.parseInt(propertyOrDefault(pr.STACKSIZE_KEY, pr.STACKSIZE_DEFAULT)),
+        Integer.parseInt(propertyOrDefault(pr.COUNT_KEY, pr.COUNT_DEFAULT)),
+        Boolean.parseBoolean(propertyOrDefault(pr.LINENUMBERS_KEY, pr.LINENUMBERS_DEFAULT)))
   }
 }
diff --git a/gradle/validation/check-environment.gradle b/gradle/validation/check-environment.gradle
index 514c191..f62e387 100644
--- a/gradle/validation/check-environment.gradle
+++ b/gradle/validation/check-environment.gradle
@@ -23,6 +23,7 @@
 configure(rootProject) {
   ext {
     expectedGradleVersion = '8.4'
+    hasJavaFlightRecorder = ModuleLayer.boot().findModule('jdk.jfr').map(this.class.module::canRead).orElse(false)
   }
 
   wrapper {
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 93bdc07..1fd0492 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -348,6 +348,9 @@
 
 * GITHUB#12655: Upgrade to Gradle 8.4 (Kevin Risden)
 
+* GITHUB#12845: Only enable support for tests.profile if jdk.jfr module is available
+  in Gradle runtime. (Uwe Schindler)
+
 Other
 ---------------------