You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ji...@apache.org on 2026/09/25 14:13:02 UTC

(geode) branch develop updated: [GEODE-10663] Gradle 8.14.5 (#8091)

This is an automated email from the ASF dual-hosted git repository.

JinwooHwang pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new 1436d3909f [GEODE-10663] Gradle 8.14.5 (#8091)
1436d3909f is described below

commit 1436d3909f4e654fae6e469e27f2d1dc4b57f26f
Author: Jinwoo Hwang <92...@users.noreply.github.com>
AuthorDate: Fri Sep 25 10:12:56 2026 -0400

    [GEODE-10663] Gradle 8.14.5 (#8091)
    
    * [GEODE-10663] Replace build script APIs removed in Gradle 8
    
    * [GEODE-10663] Resolve configurations from their owning project
    
    * [GEODE-10663] Declare RepeatTest abstract
    
    * [GEODE-10663] List japicmp old version jars lazily
    
    * [GEODE-10663] Upgrade japicmp Gradle plugin to 0.4.6
    
    * [GEODE-10663] Upgrade Gradle to 8.14.5
    
    Regenerates the wrapper via the wrapper task, adapts the repeat test executer
    and the worker process builder to the Gradle 8.14.5 test worker APIs, and
    moves the docker plugin to 0.40.0, the first release that loads on 8.14.
---
 build-tools/geode-japicmp/build.gradle             |   2 +-
 build-tools/geode-repeat-test/build.gradle         |   1 -
 .../geode/gradle/testing/repeat/RepeatTest.groovy  |   2 +-
 .../gradle/testing/repeat/RepeatTestExecuter.java  |  31 ++++++-------
 .../process/LauncherProxyWorkerProcessBuilder.java |  16 +++++--
 build-tools/scripts/build.gradle                   |   2 +-
 .../scripts/src/main/groovy/code-analysis.gradle   |  19 +++-----
 .../src/main/groovy/geode-japicmp-task.gradle      |  49 +++++++++------------
 .../scripts/src/main/groovy/geode-java.gradle      |   2 +-
 .../src/main/groovy/geode-publish-artifacts.gradle |   4 +-
 .../scripts/src/main/groovy/geode-test.gradle      |   2 +-
 .../src/main/groovy/resolve-dependencies.gradle    |  16 ++++---
 build.gradle                                       |  10 ++---
 extensions/geode-modules-assembly/build.gradle     |   8 ++--
 geode-assembly/build.gradle                        |  12 ++---
 .../GradleBuildWithGeodeCoreAcceptanceTest.java    |   2 +-
 geode-old-versions/build.gradle                    |   2 +-
 gradle.properties                                  |   2 +-
 gradle/wrapper/gradle-wrapper.jar                  | Bin 61624 -> 43764 bytes
 gradle/wrapper/gradle-wrapper.properties           |   3 +-
 gradlew                                            |  37 +++++++++-------
 gradlew.bat                                        |  26 ++++++-----
 22 files changed, 125 insertions(+), 123 deletions(-)

diff --git a/build-tools/geode-japicmp/build.gradle b/build-tools/geode-japicmp/build.gradle
index 9136fd3ecc..78faf559e2 100644
--- a/build-tools/geode-japicmp/build.gradle
+++ b/build-tools/geode-japicmp/build.gradle
@@ -27,7 +27,7 @@ repositories {
 
 dependencies {
   implementation(gradleApi())
-  implementation('me.champeau.gradle:japicmp-gradle-plugin:0.3.0')
+  implementation('me.champeau.gradle:japicmp-gradle-plugin:0.4.6')
 }
 
 sourceSets {
diff --git a/build-tools/geode-repeat-test/build.gradle b/build-tools/geode-repeat-test/build.gradle
index 18a74e8d78..c4028cb971 100644
--- a/build-tools/geode-repeat-test/build.gradle
+++ b/build-tools/geode-repeat-test/build.gradle
@@ -31,7 +31,6 @@ repositories {
 
 dependencies {
   implementation(gradleApi())
-  implementation('com.google.guava:guava:31.1-jre')
 
   testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
   testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
diff --git a/build-tools/geode-repeat-test/src/main/groovy/org/apache/geode/gradle/testing/repeat/RepeatTest.groovy b/build-tools/geode-repeat-test/src/main/groovy/org/apache/geode/gradle/testing/repeat/RepeatTest.groovy
index 451b521d39..a51ddedaea 100644
--- a/build-tools/geode-repeat-test/src/main/groovy/org/apache/geode/gradle/testing/repeat/RepeatTest.groovy
+++ b/build-tools/geode-repeat-test/src/main/groovy/org/apache/geode/gradle/testing/repeat/RepeatTest.groovy
@@ -25,7 +25,7 @@ import org.gradle.api.tasks.Input
 import org.gradle.internal.time.Clock
 import org.gradle.internal.work.WorkerLeaseService
 
-public class RepeatTest extends Test {
+public abstract class RepeatTest extends Test {
 
   @Input
   private int times = 5
diff --git a/build-tools/geode-repeat-test/src/main/java/org/apache/geode/gradle/testing/repeat/RepeatTestExecuter.java b/build-tools/geode-repeat-test/src/main/java/org/apache/geode/gradle/testing/repeat/RepeatTestExecuter.java
index 036f3c6917..65b3a15f09 100644
--- a/build-tools/geode-repeat-test/src/main/java/org/apache/geode/gradle/testing/repeat/RepeatTestExecuter.java
+++ b/build-tools/geode-repeat-test/src/main/java/org/apache/geode/gradle/testing/repeat/RepeatTestExecuter.java
@@ -14,11 +14,8 @@
  */
 package org.apache.geode.gradle.testing.repeat;
 
-import java.io.File;
-import java.util.List;
-import java.util.Set;
+import java.util.ArrayList;
 
-import com.google.common.collect.ImmutableSet;
 import org.gradle.api.file.FileTree;
 import org.gradle.api.internal.DocumentationRegistry;
 import org.gradle.api.internal.classpath.ModuleRegistry;
@@ -30,6 +27,7 @@ import org.gradle.api.internal.tasks.testing.TestResultProcessor;
 import org.gradle.api.internal.tasks.testing.WorkerTestClassProcessorFactory;
 import org.gradle.api.internal.tasks.testing.detection.DefaultTestClassScanner;
 import org.gradle.api.internal.tasks.testing.detection.DefaultTestExecuter;
+import org.gradle.api.internal.tasks.testing.detection.ForkedTestClasspathFactory;
 import org.gradle.api.internal.tasks.testing.detection.TestFrameworkDetector;
 import org.gradle.api.internal.tasks.testing.filter.DefaultTestFilter;
 import org.gradle.api.internal.tasks.testing.processors.MaxNParallelTestClassProcessor;
@@ -37,6 +35,7 @@ import org.gradle.api.internal.tasks.testing.processors.PatternMatchTestClassPro
 import org.gradle.api.internal.tasks.testing.processors.RestartEveryNTestClassProcessor;
 import org.gradle.api.internal.tasks.testing.processors.RunPreviousFailedFirstTestClassProcessor;
 import org.gradle.api.internal.tasks.testing.processors.TestMainAction;
+import org.gradle.api.internal.tasks.testing.worker.ForkedTestClasspath;
 import org.gradle.api.internal.tasks.testing.worker.ForkingTestClassProcessor;
 import org.gradle.api.logging.Logger;
 import org.gradle.api.logging.Logging;
@@ -47,7 +46,7 @@ import org.gradle.internal.work.WorkerLeaseService;
 import org.gradle.process.internal.worker.WorkerProcessFactory;
 
 /**
- * A copy of {@link DefaultTestExecuter} from Gradle v7.6.6, modified to process each test class
+ * A copy of {@link DefaultTestExecuter} from Gradle v8.14.5, modified to process each test class
  * as many times as it was submitted. This is required by our {@link RepeatTest} task, because:
  * <ul>
  *   <li>Geode's {@code RepeatTest} task operates by submitting each test class for processing
@@ -70,7 +69,7 @@ public class RepeatTestExecuter implements TestExecuter<JvmTestExecutionSpec> {
 
   private final WorkerProcessFactory workerFactory;
   private final ActorFactory actorFactory;
-  private final ModuleRegistry moduleRegistry;
+  private final ForkedTestClasspathFactory testClasspathFactory;
   private final WorkerLeaseService workerLeaseService;
   private final int maxWorkerCount;
   private final Clock clock;
@@ -85,7 +84,7 @@ public class RepeatTestExecuter implements TestExecuter<JvmTestExecutionSpec> {
       int iterationCount) {
     this.workerFactory = workerFactory;
     this.actorFactory = actorFactory;
-    this.moduleRegistry = moduleRegistry;
+    this.testClasspathFactory = new ForkedTestClasspathFactory(moduleRegistry);
     this.workerLeaseService = workerLeaseService;
     this.maxWorkerCount = maxWorkerCount;
     this.clock = clock;
@@ -99,17 +98,14 @@ public class RepeatTestExecuter implements TestExecuter<JvmTestExecutionSpec> {
       TestResultProcessor testResultProcessor) {
     final TestFramework testFramework = testExecutionSpec.getTestFramework();
     final WorkerTestClassProcessorFactory testInstanceFactory = testFramework.getProcessorFactory();
-    final Set<File> classpath = ImmutableSet.copyOf(testExecutionSpec.getClasspath());
-    final Set<File> modulePath = ImmutableSet.copyOf(testExecutionSpec.getModulePath());
-    final List<String>
-        testWorkerImplementationModules =
-        testFramework.getTestWorkerImplementationModules();
+    final ForkedTestClasspath classpath = testClasspathFactory.create(
+        testExecutionSpec.getClasspath(), testExecutionSpec.getModulePath(), testFramework,
+        testExecutionSpec.getTestIsModule());
     final Factory<TestClassProcessor> forkingProcessorFactory = () -> {
       TestClassProcessor forkingTestClassProcessor =
           new ForkingTestClassProcessor(workerLeaseService, workerFactory, testInstanceFactory,
-              testExecutionSpec.getJavaForkOptions(), classpath, modulePath,
-              testWorkerImplementationModules, testFramework.getWorkerConfigurationAction(),
-              moduleRegistry, documentationRegistry);
+              testExecutionSpec.getJavaForkOptions(), classpath,
+              testFramework.getWorkerConfigurationAction(), documentationRegistry);
       // Wrap the forking processor to make it distinguish different executions of a test class
       return new ExecutionTrackingTestClassProcessor(forkingTestClassProcessor, iterationCount);
     };
@@ -129,8 +125,9 @@ public class RepeatTestExecuter implements TestExecuter<JvmTestExecutionSpec> {
     Runnable detector;
     if (testExecutionSpec.isScanForTestClasses() && testFramework.getDetector() != null) {
       TestFrameworkDetector testFrameworkDetector = testFramework.getDetector();
-      testFrameworkDetector.setTestClasses(testExecutionSpec.getTestClassesDirs().getFiles());
-      testFrameworkDetector.setTestClasspath(classpath);
+      testFrameworkDetector
+          .setTestClasses(new ArrayList<>(testExecutionSpec.getTestClassesDirs().getFiles()));
+      testFrameworkDetector.setTestClasspath(classpath.getApplicationClasspath());
       detector = new DefaultTestClassScanner(testClassFiles, testFrameworkDetector, processor);
     } else {
       detector = new DefaultTestClassScanner(testClassFiles, null, processor);
diff --git a/build-tools/geode-testing-isolation/src/main/java/org/apache/geode/gradle/testing/process/LauncherProxyWorkerProcessBuilder.java b/build-tools/geode-testing-isolation/src/main/java/org/apache/geode/gradle/testing/process/LauncherProxyWorkerProcessBuilder.java
index 436d2d11a6..a727f76428 100644
--- a/build-tools/geode-testing-isolation/src/main/java/org/apache/geode/gradle/testing/process/LauncherProxyWorkerProcessBuilder.java
+++ b/build-tools/geode-testing-isolation/src/main/java/org/apache/geode/gradle/testing/process/LauncherProxyWorkerProcessBuilder.java
@@ -29,6 +29,7 @@ import java.util.Set;
 
 import org.gradle.api.Action;
 import org.gradle.api.logging.LogLevel;
+import org.gradle.internal.nativeintegration.services.NativeServices.NativeServicesMode;
 import org.gradle.process.internal.JavaExecHandleBuilder;
 import org.gradle.process.internal.worker.WorkerProcess;
 import org.gradle.process.internal.worker.WorkerProcessBuilder;
@@ -134,14 +135,23 @@ public class LauncherProxyWorkerProcessBuilder implements WorkerProcessBuilder {
     delegate.enableJvmMemoryInfoPublishing(shouldPublish);
   }
 
+  @Override
+  public void setNativeServicesMode(NativeServicesMode mode) {
+    delegate.setNativeServicesMode(mode);
+  }
+
+  @Override
+  public NativeServicesMode getNativeServicesMode() {
+    return delegate.getNativeServicesMode();
+  }
+
   /**
    * Returns this builder rather than the delegate's return value, because callers chain from this
    * method and must continue to hold the wrapper that installs the process launcher.
    */
-  @SuppressWarnings("deprecation")
   @Override
-  public WorkerProcessBuilder setUseLegacyAddOpens(boolean useLegacyAddOpens) {
-    delegate.setUseLegacyAddOpens(useLegacyAddOpens);
+  public WorkerProcessBuilder setAddJpmsCompatibilityFlags(boolean addJpmsCompatibilityFlags) {
+    delegate.setAddJpmsCompatibilityFlags(addJpmsCompatibilityFlags);
     return this;
   }
 
diff --git a/build-tools/scripts/build.gradle b/build-tools/scripts/build.gradle
index 9e7d7c8d9f..36cf1b2abd 100644
--- a/build-tools/scripts/build.gradle
+++ b/build-tools/scripts/build.gradle
@@ -30,7 +30,7 @@ dependencies {
   implementation('org.nosphere.apache:creadur-rat-gradle:0.7.1')
   implementation('com.github.ben-manes:gradle-versions-plugin:0.42.0')
   implementation("org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3")
-  implementation('me.champeau.gradle:japicmp-gradle-plugin:0.3.0')
+  implementation('me.champeau.gradle:japicmp-gradle-plugin:0.4.6')
 
   implementation('org.apache.geode.gradle:org.apache.geode.gradle.geode-repeat-test:1.0')
   implementation('org.apache.geode.gradle:geode-japicmp:1.0')
diff --git a/build-tools/scripts/src/main/groovy/code-analysis.gradle b/build-tools/scripts/src/main/groovy/code-analysis.gradle
index 2f35e84301..f11814fed1 100644
--- a/build-tools/scripts/src/main/groovy/code-analysis.gradle
+++ b/build-tools/scripts/src/main/groovy/code-analysis.gradle
@@ -54,19 +54,10 @@ if (project.hasProperty("codeCoverage")) {
     }
   }
 
-  tasks.register('mergeIntegrationTestCoverage', JacocoMerge) {
-    description 'Merges Distributed and Integration test coverage results'
-
-    destinationFile = file("${buildDir}/jacoco/mergedIntegrationTestCoverage.exec")
-    executionData = fileTree(dir: 'build/jacoco', include: [
-        '**/distributedTest.exec',
-        '**/integrationTest.exec'
-    ])
-  }
-
   tasks.register('jacocoIntegrationTestReport', JacocoReport) {
+    mustRunAfter tasks.withType(Test)
     reports {
-      csv.enabled false
+      csv.required = false
       sourceSets project.sourceSets.main
       html.outputLocation  = project.file("${buildDir}/reports/jacoco/integrationTest")
       executionData fileTree(dir: 'build/jacoco', include: '**/integrationTest.exec')
@@ -74,8 +65,9 @@ if (project.hasProperty("codeCoverage")) {
   }
 
   tasks.register('jacocoDistributedTestReport', JacocoReport) {
+    mustRunAfter tasks.withType(Test)
     reports {
-      csv.enabled false
+      csv.required = false
       sourceSets project.sourceSets.main
       html.outputLocation = project.file("${buildDir}/reports/jacoco/distributedTest")
       executionData fileTree(dir: 'build/jacoco', include: '**/distributedTest.exec')
@@ -83,8 +75,9 @@ if (project.hasProperty("codeCoverage")) {
   }
 
   tasks.register('jacocoOverallTestReport', JacocoReport) {
+    mustRunAfter tasks.withType(Test)
     reports {
-      csv.enabled false
+      csv.required = false
       sourceSets project.sourceSets.main
       html.outputLocation = project.file("${buildDir}/reports/jacoco/all")
       executionData fileTree(dir: 'build/jacoco', include: '**/*.exec')
diff --git a/build-tools/scripts/src/main/groovy/geode-japicmp-task.gradle b/build-tools/scripts/src/main/groovy/geode-japicmp-task.gradle
index c3cdff2735..3d0546f58b 100644
--- a/build-tools/scripts/src/main/groovy/geode-japicmp-task.gradle
+++ b/build-tools/scripts/src/main/groovy/geode-japicmp-task.gradle
@@ -33,27 +33,24 @@ tasks.register('japicmp', JapicmpTask) {
   inputs.files { ourUnpackTaskProvider }
 
   def d = java.nio.file.Paths.get(project(":geode-old-versions:${newest}").buildDir.path.toString(), "apache-geode-${newest}", 'lib')
-  // Dirty hack, to set the value as requied in configuration, 
-  // but then reset to the acutal unpacked jars on runtime.
-  oldClasspath = files()
-  oldArchives = files()
-  doFirst {
-    oldClasspath = files(file(d).listFiles())
-    oldArchives = files(file(d).listFiles(new FilenameFilter() {
+  // The unpacked jars are listed when the task runs, after the download has completed.
+  oldClasspath.setFrom(files({ file(d).listFiles() }))
+  oldArchives.setFrom(files({
+    file(d).listFiles(new FilenameFilter() {
       boolean accept(File dir, String name) {
         return name.toLowerCase().startsWith("geode-") && name.toLowerCase().endsWith(".jar")
       };
-    }))
-  }
+    })
+  }))
 
-  newClasspath = configurations.runtimeClasspath
-  newArchives = configurations.runtimeClasspath.filter { File f ->
+  newClasspath.setFrom(configurations.runtimeClasspath)
+  newArchives.setFrom(configurations.runtimeClasspath.filter { File f ->
     f.toString().contains("geode-") && f.toString().endsWith(".jar")
-  }
+  })
 
-  ignoreMissingClasses = true
-  onlyModified = true
-  accessModifier = "protected"
+  ignoreMissingClasses.set(true)
+  onlyModified.set(true)
+  accessModifier.set("protected")
 
   def allowMajorBreaking = false
   if (new DefaultArtifactVersion(version).majorVersion > new DefaultArtifactVersion(newest).majorVersion) {
@@ -67,19 +64,17 @@ tasks.register('japicmp', JapicmpTask) {
 //  includeSynthetic = true
 
   def reportFileName = "japi-v${newest}-${version}"
-  txtOutputFile = file("$buildDir/reports/${reportFileName}.txt")
-  htmlOutputFile = file("$buildDir/reports/${reportFileName}.html")
-  packageExcludes = ['*internal*']
-  packageIncludes = ['org.apache.geode.*']
-  annotationExcludes = ['@org.apache.geode.annotations.Experimental']
+  txtOutputFile.set(file("$buildDir/reports/${reportFileName}.txt"))
+  htmlOutputFile.set(file("$buildDir/reports/${reportFileName}.html"))
+  packageExcludes.set(['*internal*'])
+  packageIncludes.set(['org.apache.geode.*'])
+  annotationExcludes.set(['@org.apache.geode.annotations.Experimental'])
 
   richReport {
-    title = "Geode API Compatibility Report"
-    description = "Comparing current ${version} against downloaded v${newest}."
-    reportName = "rich-report-${reportFileName}.html"
-    outputs.files {
-      reportName
-    }
+    title.set("Geode API Compatibility Report")
+    description.set("Comparing current ${version} against downloaded v${newest}.".toString())
+    destinationDir.set(file("$buildDir/reports"))
+    reportName.set("rich-report-${reportFileName}.html".toString())
 
     if (allowMajorBreaking) {
       addRule(AllowMajorBreakingChanges)
@@ -89,6 +84,6 @@ tasks.register('japicmp', JapicmpTask) {
       addRule(GeodeApiRegressionRule)
       addRule(GeodeSpiRegressionRule)
     }
-    addDefaultRules = true
+    addDefaultRules.set(true)
   }
 }
diff --git a/build-tools/scripts/src/main/groovy/geode-java.gradle b/build-tools/scripts/src/main/groovy/geode-java.gradle
index 148309f02b..3cdfbd441f 100644
--- a/build-tools/scripts/src/main/groovy/geode-java.gradle
+++ b/build-tools/scripts/src/main/groovy/geode-java.gradle
@@ -192,7 +192,7 @@ tasks.register('jarTest', Jar) {
   dependsOn testClasses
   description 'Assembles a jar archive of test classes.'
   from sourceSets.test.output
-  classifier 'test'
+  archiveClassifier = 'test'
 }
 
 artifacts {
diff --git a/build-tools/scripts/src/main/groovy/geode-publish-artifacts.gradle b/build-tools/scripts/src/main/groovy/geode-publish-artifacts.gradle
index ce94ce21da..ad9bcd0541 100644
--- a/build-tools/scripts/src/main/groovy/geode-publish-artifacts.gradle
+++ b/build-tools/scripts/src/main/groovy/geode-publish-artifacts.gradle
@@ -21,14 +21,14 @@ task sourcesJar(type: Jar) {
   from {
     sourceSets.main.allJava
   }
-  classifier = 'sources'
+  archiveClassifier = 'sources'
 }
 
 task javadocJar(type: Jar) {
   from {
     javadoc
   }
-  classifier = 'javadoc'
+  archiveClassifier = 'javadoc'
 }
 
 publishing {
diff --git a/build-tools/scripts/src/main/groovy/geode-test.gradle b/build-tools/scripts/src/main/groovy/geode-test.gradle
index 4b31ae8a73..d23396dcc0 100644
--- a/build-tools/scripts/src/main/groovy/geode-test.gradle
+++ b/build-tools/scripts/src/main/groovy/geode-test.gradle
@@ -175,7 +175,7 @@ gradle.taskGraph.whenReady({ graph ->
       def resultsDir = TestPropertiesWriter.testResultsDir(buildDir, test.name)
       test.workingDir = resultsDir
 
-      reports.html.destination = file "$buildDir/reports/$name"
+      reports.html.outputLocation = file "$buildDir/reports/$name"
       testLogging {
         exceptionFormat = 'full'
       }
diff --git a/build-tools/scripts/src/main/groovy/resolve-dependencies.gradle b/build-tools/scripts/src/main/groovy/resolve-dependencies.gradle
index fa67a451ea..c6f1c6914c 100644
--- a/build-tools/scripts/src/main/groovy/resolve-dependencies.gradle
+++ b/build-tools/scripts/src/main/groovy/resolve-dependencies.gradle
@@ -15,21 +15,25 @@
  * limitations under the License.
  */
 
-task resolveDependencies {
-  doLast {
-    project.rootProject.allprojects.each { subProject ->
-      subProject.buildscript.configurations.each { configuration ->
+// Each project resolves its own configurations, so running resolveDependencies from the root
+// resolves the configurations of every project.
+allprojects {
+  tasks.register('resolveDependencies') {
+    doLast {
+      project.buildscript.configurations.each { configuration ->
         resolveConfiguration(configuration)
       }
-      subProject.configurations.each { configuration ->
+      project.configurations.each { configuration ->
         resolveConfiguration(configuration)
       }
     }
   }
 }
 
+// The default and archives configurations are not meant to be resolved; the classpath
+// configurations resolved alongside them cover the same dependencies.
 void resolveConfiguration(configuration) {
-  if (configuration.canBeResolved) {
+  if (configuration.canBeResolved && !(configuration.name in ['default', 'archives'])) {
     configuration.resolve()
   }
 }
diff --git a/build.gradle b/build.gradle
index 7a79754c64..e727f23f43 100755
--- a/build.gradle
+++ b/build.gradle
@@ -24,7 +24,7 @@ plugins {
   id "com.diffplug.spotless" version "6.4.1" apply false
   id "com.github.ben-manes.versions" version "0.42.0" apply false
   id "nebula.lint" version "17.7.0" apply false
-  id "com.palantir.docker" version "0.32.0" apply false
+  id "com.palantir.docker" version "0.40.0" apply false
   id "io.spring.dependency-management" version "1.0.11.RELEASE" apply false
   id "org.ajoberstar.grgit" version "4.1.1" apply false
   id "org.nosphere.apache.rat" version "0.7.1" apply false
@@ -95,7 +95,7 @@ allprojects {
 
 task combineReports(type: TestReport) {
   description 'Combines the test reports.'
-  destinationDir = file "${rootProject.buildDir}/reports/combined"
+  destinationDirectory = file "${rootProject.buildDir}/reports/combined"
   // Collect all Test tasks in subprojects
   def allTests = subprojects.collect { it.tasks.withType(Test) }.flatten()
 
@@ -103,7 +103,7 @@ task combineReports(type: TestReport) {
   allTests += tasks.getByPath(":geode-old-versions:test")
 
   // Tell TestReport to use their results
-  reportOn allTests
+  testResults.from(allTests.collect { it.binaryResultsDirectory })
 
   // Explicitly depend on them so results exist before combining
   dependsOn allTests
@@ -243,7 +243,7 @@ if (project.hasProperty('askpass')) {
 }
 
 gradle.taskGraph.whenReady({ graph ->
-  tasks.getByName('combineReports').reportOn rootProject.subprojects.collect {
+  tasks.getByName('combineReports').testResults.from(rootProject.subprojects.collect {
     it.tasks.withType(Test)
-  }.flatten()
+  }.flatten().collect { it.binaryResultsDirectory })
 })
diff --git a/extensions/geode-modules-assembly/build.gradle b/extensions/geode-modules-assembly/build.gradle
index f1fb1873d1..214a4860f4 100644
--- a/extensions/geode-modules-assembly/build.gradle
+++ b/extensions/geode-modules-assembly/build.gradle
@@ -43,7 +43,7 @@ def moduleBaseName = "Apache_Geode_Modules"
 
 def configureTcServerAssembly = {
   archiveBaseName = moduleBaseName
-  classifier = "tcServer"
+  archiveClassifier = "tcServer"
 
   // All client-server files
   into('geode-cs/lib') {
@@ -121,7 +121,7 @@ def configureTcServerAssembly = {
 
 def configureTcServer30Assembly = {
   archiveBaseName = moduleBaseName
-  classifier = "tcServer30"
+  archiveClassifier = "tcServer30"
 
   into('geode-cs-tomcat-10/conf') {
     from('release/tcserver/geode-cs-tomcat-10') {
@@ -138,7 +138,7 @@ def configureTcServer30Assembly = {
 
 tasks.register('distTomcat', Zip) {
   archiveBaseName = moduleBaseName
-  classifier = "Tomcat"
+  archiveClassifier = "Tomcat"
 
   // All client-server files
   into('lib') {
@@ -163,7 +163,7 @@ tasks.register('distTomcat', Zip) {
 
 tasks.register('distAppServer', Zip) {
   archiveBaseName = moduleBaseName
-  classifier = "AppServer"
+  archiveClassifier = "AppServer"
 
   into('lib') {
     from project(':extensions:geode-modules').tasks.named('jar')
diff --git a/geode-assembly/build.gradle b/geode-assembly/build.gradle
index 93eab9f592..89f0679d18 100755
--- a/geode-assembly/build.gradle
+++ b/geode-assembly/build.gradle
@@ -338,11 +338,8 @@ acceptanceTest {
 }
 
 tasks.register('defaultDistributionConfig', JavaExec) {
-  inputs.files {
-    project(':geode-core').sourceSets.getByName('main').runtimeClasspath
-  }
   outputs.file file("$buildDir/gemfire.properties")
-  main 'org.apache.geode.distributed.internal.DefaultPropertiesGenerator'
+  mainClass = 'org.apache.geode.distributed.internal.DefaultPropertiesGenerator'
   classpath configurations.defaultDistributionConfigClasspath
   workingDir buildDir
 
@@ -352,11 +349,8 @@ tasks.register('defaultDistributionConfig', JavaExec) {
 }
 
 tasks.register('defaultCacheConfig', JavaExec) {
-  inputs.files {
-    project(':geode-core').sourceSets.getByName('main').runtimeClasspath
-  }
   outputs.file file("$buildDir/cache.xml")
-  main 'org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator'
+  mainClass = 'org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator'
   classpath configurations.defaultCacheConfigClasspath
   workingDir buildDir
 
@@ -610,7 +604,7 @@ distributions {
 build.dependsOn(installDist)
 
 tasks.named('srcDistTar').configure {
-  classifier 'src'
+  archiveClassifier = 'src'
 }
 
 [
diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/rest/GradleBuildWithGeodeCoreAcceptanceTest.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/rest/GradleBuildWithGeodeCoreAcceptanceTest.java
index 7142c21fcf..be6a57358f 100644
--- a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/rest/GradleBuildWithGeodeCoreAcceptanceTest.java
+++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/rest/GradleBuildWithGeodeCoreAcceptanceTest.java
@@ -66,7 +66,7 @@ public class GradleBuildWithGeodeCoreAcceptanceTest {
     copyDirectoryResource(projectDir, buildDir);
 
     GradleConnector connector = GradleConnector.newConnector();
-    connector.useGradleVersion("7.6.6");
+    connector.useGradleVersion("8.14.5");
     connector.forProjectDirectory(buildDir);
 
     ProjectConnection connection = connector.connect();
diff --git a/geode-old-versions/build.gradle b/geode-old-versions/build.gradle
index 059248bff8..291817bc51 100644
--- a/geode-old-versions/build.gradle
+++ b/geode-old-versions/build.gradle
@@ -140,7 +140,7 @@ sourceSets {
 }
 tasks.register('geodeOldVersionClasspathsJar', Jar) {
   from sourceSets.oldVersions.output
-  classifier 'oldVersions'
+  archiveClassifier = 'oldVersions'
 }
 
 artifacts {
diff --git a/gradle.properties b/gradle.properties
index b31cff6130..50609e2325 100755
--- a/gradle.properties
+++ b/gradle.properties
@@ -47,7 +47,7 @@ buildId = 0
 productName = Apache Geode
 productOrg = Apache Software Foundation (ASF)
 
-minimumGradleVersion = 7.6.6
+minimumGradleVersion = 8.14.5
 # Set this on the command line with -P or in ~/.gradle/gradle.properties
 # to change the buildDir location.  Use an absolute path.
 buildRoot=
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index afba109285..1b33c55baa 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index f429f1b9ea..70fe02a536 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,7 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.6-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-all.zip
 networkTimeout=10000
+validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 65dcd68d65..23d15a9367 100755
--- a/gradlew
+++ b/gradlew
@@ -15,6 +15,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+# SPDX-License-Identifier: Apache-2.0
+#
 
 ##############################################################################
 #
@@ -55,7 +57,7 @@
 #       Darwin, MinGW, and NonStop.
 #
 #   (3) This script is generated from the Groovy template
-#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
 #       within the Gradle project.
 #
 #       You can find Gradle at https://github.com/gradle/gradle/.
@@ -83,10 +85,8 @@ done
 # This is normally unused
 # shellcheck disable=SC2034
 APP_BASE_NAME=${0##*/}
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
 
 # Use the maximum available, or set MAX_FD != -1 to use that value.
 MAX_FD=maximum
@@ -114,7 +114,7 @@ case "$( uname )" in                #(
   NONSTOP* )        nonstop=true ;;
 esac
 
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+CLASSPATH="\\\"\\\""
 
 
 # Determine the Java command to use to start the JVM.
@@ -133,10 +133,13 @@ location of your Java installation."
     fi
 else
     JAVACMD=java
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+    if ! command -v java >/dev/null 2>&1
+    then
+        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 
 Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
+    fi
 fi
 
 # Increase the maximum file descriptors if we can.
@@ -144,7 +147,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
     case $MAX_FD in #(
       max*)
         # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
-        # shellcheck disable=SC3045 
+        # shellcheck disable=SC2039,SC3045
         MAX_FD=$( ulimit -H -n ) ||
             warn "Could not query maximum file descriptor limit"
     esac
@@ -152,7 +155,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
       '' | soft) :;; #(
       *)
         # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
-        # shellcheck disable=SC3045 
+        # shellcheck disable=SC2039,SC3045
         ulimit -n "$MAX_FD" ||
             warn "Could not set maximum file descriptor limit to $MAX_FD"
     esac
@@ -197,16 +200,20 @@ if "$cygwin" || "$msys" ; then
     done
 fi
 
-# Collect all arguments for the java command;
-#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
-#     shell script including quotes and variable substitutions, so put them in
-#     double quotes to make sure that they get re-expanded; and
-#   * put everything else in single quotes, so that it's not re-expanded.
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+#     and any embedded shellness will be escaped.
+#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+#     treated as '${Hostname}' itself on the command line.
 
 set -- \
         "-Dorg.gradle.appname=$APP_BASE_NAME" \
         -classpath "$CLASSPATH" \
-        org.gradle.wrapper.GradleWrapperMain \
+        -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
         "$@"
 
 # Stop when "xargs" is not available.
diff --git a/gradlew.bat b/gradlew.bat
index 6689b85bee..5eed7ee845 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -13,6 +13,8 @@
 @rem See the License for the specific language governing permissions and
 @rem limitations under the License.
 @rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
 
 @if "%DEBUG%"=="" @echo off
 @rem ##########################################################################
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
 %JAVA_EXE% -version >NUL 2>&1
 if %ERRORLEVEL% equ 0 goto execute
 
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
 
 goto fail
 
@@ -57,22 +59,22 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
 
 if exist "%JAVA_EXE%" goto execute
 
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
 
 goto fail
 
 :execute
 @rem Setup the command line
 
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+set CLASSPATH=
 
 
 @rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
 
 :end
 @rem End local scope for the variables with windows NT shell