Selaa lähdekoodia

[8.19] Update Gradle wrapper to 9.0.0 (#132932) (#133165)

* Update Gradle wrapper to 9.0.0 (#132932)

Updating to the latest Gradle GA version to keep our build uptodate

* Rework RestCompatTestTransformTask to CC compatibility
* Fix build integration tests due to api changes
* Updating javaparser

(cherry picked from commit 8e2c948d44f24999f7b70aa126cd0d6e9ede8c18)

# Conflicts:
#	build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/idea/IdeaXmlUtil.java
#	build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/compat/compat/RestCompatTestTransformTask.java
#	build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/close_to/ReplaceValueInCloseTo.java
#	build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/text/ReplaceIsTrue.java
#	build-tools-internal/src/main/resources/minimumGradleVersion
#	build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/test/rest/transform/close_to/ReplaceValueInCloseToTests.java

* Fix merge conflict

* More fixes lost in backports

* Fix docker bin context copy
Rene Groeschke 2 kuukautta sitten
vanhempi
commit
9cd45990c4
35 muutettua tiedostoa jossa 186 lisäystä ja 97 poistoa
  1. 2 2
      build-tools-internal/gradle/wrapper/gradle-wrapper.properties
  2. 4 2
      build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/fixtures/AbstractRestResourcesFuncTest.groovy
  3. 3 8
      build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/InternalDistributionArchiveSetupPluginFuncTest.groovy
  4. 0 1
      build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/InternalDistributionBwcSetupPluginFuncTest.groovy
  5. 14 8
      build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/SymbolicLinkPreservingTarFuncTest.groovy
  6. 0 0
      build-tools-internal/src/integTest/resources/org/elasticsearch/gradle/internal/fake_git/remote/distribution/bwc/bugfix3/build.gradle
  7. 0 0
      build-tools-internal/src/integTest/resources/org/elasticsearch/gradle/internal/fake_git/remote/distribution/bwc/bugfix4/build.gradle
  8. 0 0
      build-tools-internal/src/integTest/resources/org/elasticsearch/gradle/internal/fake_git/remote/distribution/bwc/bugfix5/build.gradle
  9. 0 0
      build-tools-internal/src/integTest/resources/org/elasticsearch/gradle/internal/fake_git/remote/distribution/bwc/staged2/build.gradle
  10. 2 0
      build-tools-internal/src/main/groovy/elasticsearch.ide.gradle
  11. 5 4
      build-tools-internal/src/main/groovy/org/elasticsearch/gradle/internal/AntTask.groovy
  12. 2 0
      build-tools-internal/src/main/groovy/org/elasticsearch/gradle/internal/test/AntFixture.groovy
  13. 1 1
      build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/SymbolicLinkPreservingTar.java
  14. 11 10
      build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/compat/compat/RestCompatTestTransformTask.java
  15. 17 5
      build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/ReplaceByKey.java
  16. 44 0
      build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/SerializableJsonNode.java
  17. 5 5
      build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/length/ReplaceValueInLength.java
  18. 5 4
      build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/match/AddMatch.java
  19. 4 4
      build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/match/ReplaceValueInMatch.java
  20. 4 2
      build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/text/ReplaceIsFalse.java
  21. 3 1
      build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/text/ReplaceIsTrue.java
  22. 11 5
      build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/text/ReplaceTextual.java
  23. 1 1
      build-tools-internal/src/main/resources/minimumGradleVersion
  24. 2 2
      build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/UpdateVersionsTaskTests.java
  25. 2 1
      build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/test/rest/transform/length/ReplaceValueInLengthTests.java
  26. 3 2
      build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/test/rest/transform/match/AddMatchTests.java
  27. 2 1
      build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/test/rest/transform/match/ReplaceValueInMatchTests.java
  28. 4 9
      build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/test/rest/transform/text/ReplaceTextualTests.java
  29. 2 1
      build-tools/src/testFixtures/groovy/org/elasticsearch/gradle/fixtures/AbstractGradleFuncTest.groovy
  30. 2 0
      build.gradle
  31. 3 0
      distribution/docker/build.gradle
  32. 2 2
      gradle/build.versions.toml
  33. 22 12
      gradle/verification-metadata.xml
  34. 2 2
      gradle/wrapper/gradle-wrapper.properties
  35. 2 2
      plugins/examples/gradle/wrapper/gradle-wrapper.properties

+ 2 - 2
build-tools-internal/gradle/wrapper/gradle-wrapper.properties

@@ -1,7 +1,7 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionSha256Sum=443c9c8ee2ac1ee0e11881a40f2376d79c66386264a44b24a9f8ca67e633375f
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-all.zip
+distributionSha256Sum=f759b8dd5204e2e3fa4ca3e73f452f087153cf81bac9561eeb854229cc2c5365
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-all.zip
 networkTimeout=10000
 validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME

+ 4 - 2
build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/fixtures/AbstractRestResourcesFuncTest.groovy

@@ -53,8 +53,10 @@ abstract class AbstractRestResourcesFuncTest extends AbstractGradleFuncTest {
         }
         """
 
-        subProject(":distribution:archives:integ-test-zip") << "configurations.create('extracted')\n"
-        subProject(":distribution:archives:integ-test-zip") << "configurations.create('default')\n"
+        subProject(":distribution:archives:integ-test-zip") << """
+apply plugin: 'base'
+configurations.create('extracted')
+"""
     }
 
     void setupRestResources(List<String> apis, List<String> tests = [], List<String> xpackTests = []) {

+ 3 - 8
build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/InternalDistributionArchiveSetupPluginFuncTest.groovy

@@ -80,11 +80,8 @@ class InternalDistributionArchiveSetupPluginFuncTest extends AbstractGradleFuncT
     def "registered distribution provides archives and directory variant"() {
         given:
         file('someFile.txt') << "some content"
-
-        settingsFile << """
-            include ':consumer'
-            include ':producer-tar'
-        """
+        subProject("consumer")
+        subProject("producer-tar")
 
         buildFile << """
         import org.gradle.api.artifacts.type.ArtifactTypeDefinition;
@@ -154,9 +151,7 @@ class InternalDistributionArchiveSetupPluginFuncTest extends AbstractGradleFuncT
     def "builds extracted distribution via extractedAssemble"() {
         given:
         file('someFile.txt') << "some content"
-        settingsFile << """
-            include ':producer-tar'
-        """
+        subProject("producer-tar")
 
         buildFile << """
         import org.gradle.api.artifacts.type.ArtifactTypeDefinition;

+ 0 - 1
build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/InternalDistributionBwcSetupPluginFuncTest.groovy

@@ -117,5 +117,4 @@ class InternalDistributionBwcSetupPluginFuncTest extends AbstractGitAwareGradleF
         result.output.contains("nested folder /distribution/bwc/minor/build/bwc/checkout-8.x/" +
                         "distribution/archives/darwin-tar/build/install/elasticsearch-8.4.0-SNAPSHOT")
     }
-
 }

+ 14 - 8
build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/SymbolicLinkPreservingTarFuncTest.groovy

@@ -9,7 +9,8 @@
 
 package org.elasticsearch.gradle.internal
 
-import spock.lang.Ignore
+
+import spock.lang.Unroll
 
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry
 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream
@@ -17,7 +18,6 @@ import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream
 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream
 import org.elasticsearch.gradle.fixtures.AbstractGradleFuncTest
 import org.gradle.api.GradleException
-import spock.lang.Unroll
 
 import java.nio.file.Files
 import java.nio.file.Path
@@ -66,8 +66,12 @@ tasks.register("buildBZip2Tar", SymbolicLinkPreservingTar) { SymbolicLinkPreserv
   from fileTree("archiveRoot")
 
   into('config') {
-    dirMode 0750
-    fileMode 0660
+    dirPermissions {
+        unix(0750)
+    }
+    filePermissions {
+        unix(0660)
+    }
     from "real-folder2"
   }
 }
@@ -118,8 +122,10 @@ tasks.register("buildTar", SymbolicLinkPreservingTar) { SymbolicLinkPreservingTa
         preserverTimestamp << [true, false]
     }
 
-    private boolean assertTar(final File archive, final Function<? super FileInputStream, ? extends InputStream> wrapper, boolean preserveFileTimestamps)
-            throws IOException {
+    private boolean assertTar(final File archive,
+                              final Function<? super FileInputStream, ? extends InputStream> wrapper,
+                              boolean preserveFileTimestamps)
+        throws IOException {
         try (TarArchiveInputStream tar = new TarArchiveInputStream(wrapper.apply(new FileInputStream(archive)))) {
             TarArchiveEntry entry = tar.getNextTarEntry();
             boolean realFolderEntry = false;
@@ -132,7 +138,7 @@ tasks.register("buildTar", SymbolicLinkPreservingTar) { SymbolicLinkPreservingTa
                 if (entry.getName().equals("real-folder/")) {
                     assert entry.isDirectory()
                     realFolderEntry = true
-                }  else if (entry.getName().equals("real-folder/file")) {
+                } else if (entry.getName().equals("real-folder/file")) {
                     assert entry.isFile()
                     fileEntry = true
                 } else if (entry.getName().equals("real-folder/link-to-file")) {
@@ -145,7 +151,7 @@ tasks.register("buildTar", SymbolicLinkPreservingTar) { SymbolicLinkPreservingTa
                 } else if (entry.getName().equals("config/sub/")) {
                     assert entry.isDirectory()
                     assert entry.getMode() == 16872
-                }else if (entry.getName().equals("link-in-folder/")) {
+                } else if (entry.getName().equals("link-in-folder/")) {
                     assert entry.isDirectory()
                     linkInFolderEntry = true
                 } else if (entry.getName().equals("link-in-folder/link-to-file")) {

+ 0 - 0
build-tools-internal/src/integTest/resources/org/elasticsearch/gradle/internal/fake_git/remote/distribution/bwc/bugfix3/build.gradle


+ 0 - 0
build-tools-internal/src/integTest/resources/org/elasticsearch/gradle/internal/fake_git/remote/distribution/bwc/bugfix4/build.gradle


+ 0 - 0
build-tools-internal/src/integTest/resources/org/elasticsearch/gradle/internal/fake_git/remote/distribution/bwc/bugfix5/build.gradle


+ 0 - 0
build-tools-internal/src/integTest/resources/org/elasticsearch/gradle/internal/fake_git/remote/distribution/bwc/staged2/build.gradle


+ 2 - 0
build-tools-internal/src/main/groovy/elasticsearch.ide.gradle

@@ -16,6 +16,8 @@ import org.jetbrains.gradle.ext.JUnit
 import java.nio.file.Files
 import java.nio.file.Paths
 import java.nio.file.StandardCopyOption
+import groovy.xml.XmlParser
+import groovy.xml.XmlNodePrinter
 
 allprojects {
   apply plugin: 'idea'

+ 5 - 4
build-tools-internal/src/main/groovy/org/elasticsearch/gradle/internal/AntTask.groovy

@@ -9,18 +9,18 @@
 
 package org.elasticsearch.gradle.internal
 
+import groovy.ant.AntBuilder
+
 import org.apache.tools.ant.BuildListener
 import org.apache.tools.ant.BuildLogger
 import org.apache.tools.ant.DefaultLogger
 import org.apache.tools.ant.Project
 import org.gradle.api.DefaultTask
-import org.gradle.api.GradleException
 import org.gradle.api.file.FileSystemOperations
-import org.gradle.api.tasks.Input
 import org.gradle.api.tasks.TaskAction
 
-import javax.inject.Inject
 import java.nio.charset.Charset
+import javax.inject.Inject
 
 /**
  * A task which will run ant commands.
@@ -83,7 +83,8 @@ public abstract class AntTask extends DefaultTask {
         return new DefaultLogger(
             errorPrintStream: stream,
             outputPrintStream: stream,
-            messageOutputLevel: outputLevel)
+            messageOutputLevel: outputLevel
+        )
     }
 
     /**

+ 2 - 0
build-tools-internal/src/main/groovy/org/elasticsearch/gradle/internal/test/AntFixture.groovy

@@ -9,6 +9,8 @@
 
 package org.elasticsearch.gradle.internal.test
 
+import groovy.ant.AntBuilder
+
 import org.elasticsearch.gradle.OS
 
 import org.elasticsearch.gradle.internal.AntFixtureStop

+ 1 - 1
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/SymbolicLinkPreservingTar.java

@@ -41,7 +41,7 @@ import java.util.Set;
  *
  * This task is necessary because the built-in task {@link org.gradle.api.tasks.bundling.Tar} does not preserve symbolic links.
  */
-public class SymbolicLinkPreservingTar extends Tar {
+public abstract class SymbolicLinkPreservingTar extends Tar {
 
     @Override
     protected CopyAction createCopyAction() {

+ 11 - 10
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/compat/compat/RestCompatTestTransformTask.java

@@ -26,6 +26,7 @@ import org.elasticsearch.gradle.Version;
 import org.elasticsearch.gradle.VersionProperties;
 import org.elasticsearch.gradle.internal.test.rest.transform.RestTestTransform;
 import org.elasticsearch.gradle.internal.test.rest.transform.RestTestTransformer;
+import org.elasticsearch.gradle.internal.test.rest.transform.SerializableJsonNode;
 import org.elasticsearch.gradle.internal.test.rest.transform.do_.ReplaceKeyInDo;
 import org.elasticsearch.gradle.internal.test.rest.transform.headers.InjectHeaders;
 import org.elasticsearch.gradle.internal.test.rest.transform.length.ReplaceKeyInLength;
@@ -168,7 +169,7 @@ public abstract class RestCompatTestTransformTask extends DefaultTask {
      * @param value  the value used in the replacement. For example "bar"
      */
     public void replaceValueInMatch(String subKey, Object value) {
-        getTransformations().add(new ReplaceValueInMatch(subKey, MAPPER.convertValue(value, JsonNode.class)));
+        getTransformations().add(new ReplaceValueInMatch(subKey, SerializableJsonNode.of(value, JsonNode.class)));
     }
 
     /**
@@ -179,7 +180,7 @@ public abstract class RestCompatTestTransformTask extends DefaultTask {
      * @param testName the testName to apply replacement
      */
     public void replaceValueInMatch(String subKey, Object value, String testName) {
-        getTransformations().add(new ReplaceValueInMatch(subKey, MAPPER.convertValue(value, JsonNode.class), testName));
+        getTransformations().add(new ReplaceValueInMatch(subKey, SerializableJsonNode.of(value, JsonNode.class), testName));
     }
 
     /**
@@ -224,7 +225,7 @@ public abstract class RestCompatTestTransformTask extends DefaultTask {
      * @param value  the value used in the replacement. For example 99
      */
     public void replaceValueInLength(String subKey, int value) {
-        getTransformations().add(new ReplaceValueInLength(subKey, MAPPER.convertValue(value, NumericNode.class)));
+        getTransformations().add(new ReplaceValueInLength(subKey, SerializableJsonNode.of(value, NumericNode.class)));
     }
 
     /**
@@ -236,7 +237,7 @@ public abstract class RestCompatTestTransformTask extends DefaultTask {
      * @param testName the testName to apply replacement
      */
     public void replaceValueInLength(String subKey, int value, String testName) {
-        getTransformations().add(new ReplaceValueInLength(subKey, MAPPER.convertValue(value, NumericNode.class), testName));
+        getTransformations().add(new ReplaceValueInLength(subKey, SerializableJsonNode.of(value, NumericNode.class), testName));
     }
 
     /**
@@ -258,7 +259,7 @@ public abstract class RestCompatTestTransformTask extends DefaultTask {
      * @param newValue the value used in the replacement
      */
     public void replaceIsTrue(String oldValue, Object newValue) {
-        getTransformations().add(new ReplaceIsTrue(oldValue, MAPPER.convertValue(newValue, TextNode.class)));
+        getTransformations().add(new ReplaceIsTrue(oldValue, SerializableJsonNode.of(newValue, TextNode.class)));
     }
 
     /**
@@ -269,7 +270,7 @@ public abstract class RestCompatTestTransformTask extends DefaultTask {
      * @param newValue the value used in the replacement
      */
     public void replaceIsFalse(String oldValue, Object newValue) {
-        getTransformations().add(new ReplaceIsFalse(oldValue, MAPPER.convertValue(newValue, TextNode.class)));
+        getTransformations().add(new ReplaceIsFalse(oldValue, SerializableJsonNode.of(newValue, TextNode.class)));
     }
 
     /**
@@ -281,7 +282,7 @@ public abstract class RestCompatTestTransformTask extends DefaultTask {
      * @param testName the testName to apply replacement
      */
     public void replaceIsFalse(String oldValue, Object newValue, String testName) {
-        getTransformations().add(new ReplaceIsFalse(oldValue, MAPPER.convertValue(newValue, TextNode.class), testName));
+        getTransformations().add(new ReplaceIsFalse(oldValue, SerializableJsonNode.of(newValue, TextNode.class), testName));
     }
 
     /**
@@ -293,7 +294,7 @@ public abstract class RestCompatTestTransformTask extends DefaultTask {
      * @param newValue the value used in the replacement
      */
     public void replaceValueTextByKeyValue(String key, String oldValue, Object newValue) {
-        getTransformations().add(new ReplaceTextual(key, oldValue, MAPPER.convertValue(newValue, TextNode.class)));
+        getTransformations().add(new ReplaceTextual(key, oldValue, SerializableJsonNode.of(newValue, TextNode.class)));
     }
 
     /**
@@ -306,7 +307,7 @@ public abstract class RestCompatTestTransformTask extends DefaultTask {
      * @param testName the testName to apply replacement
      */
     public void replaceValueTextByKeyValue(String key, String oldValue, Object newValue, String testName) {
-        getTransformations().add(new ReplaceTextual(key, oldValue, MAPPER.convertValue(newValue, TextNode.class), testName));
+        getTransformations().add(new ReplaceTextual(key, oldValue, SerializableJsonNode.of(newValue, TextNode.class), testName));
     }
 
     /**
@@ -340,7 +341,7 @@ public abstract class RestCompatTestTransformTask extends DefaultTask {
      * @param testName the testName to apply addition
      */
     public void addMatch(String subKey, Object value, String testName) {
-        getTransformations().add(new AddMatch(subKey, MAPPER.convertValue(value, JsonNode.class), testName));
+        getTransformations().add(new AddMatch(subKey, SerializableJsonNode.of(value, JsonNode.class), testName));
     }
 
     /**

+ 17 - 5
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/ReplaceByKey.java

@@ -10,6 +10,7 @@
 package org.elasticsearch.gradle.internal.test.rest.transform;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 
 import org.gradle.api.tasks.Input;
 import org.gradle.api.tasks.Optional;
@@ -25,18 +26,23 @@ import org.gradle.api.tasks.Optional;
 public abstract class ReplaceByKey implements RestTestTransformByParentObject {
     private final String requiredChildKey;
     private final String newChildKey;
-    private final JsonNode replacementNode;
+    private final SerializableJsonNode replacementNode;
     private final String testName;
 
-    public ReplaceByKey(String requiredChildKey, JsonNode replacementNode) {
+    public ReplaceByKey(String requiredChildKey, SerializableJsonNode<JsonNode> replacementNode) {
         this(requiredChildKey, replacementNode, null);
     }
 
-    public ReplaceByKey(String requiredChildKey, JsonNode replacementNode, String testName) {
+    public ReplaceByKey(String requiredChildKey, SerializableJsonNode<JsonNode> replacementNode, String testName) {
         this(requiredChildKey, requiredChildKey, replacementNode, testName);
     }
 
-    public ReplaceByKey(String requiredChildKey, String newChildKey, JsonNode replacementNode, String testName) {
+    public ReplaceByKey(
+        String requiredChildKey,
+        String newChildKey,
+        SerializableJsonNode<? extends JsonNode> replacementNode,
+        String testName
+    ) {
         this.requiredChildKey = requiredChildKey;
         this.newChildKey = newChildKey;
         this.replacementNode = replacementNode;
@@ -60,7 +66,7 @@ public abstract class ReplaceByKey implements RestTestTransformByParentObject {
 
     @Input
     @Optional
-    public JsonNode getReplacementNode() {
+    public SerializableJsonNode<? extends JsonNode> getReplacementNode() {
         return replacementNode;
     }
 
@@ -69,4 +75,10 @@ public abstract class ReplaceByKey implements RestTestTransformByParentObject {
     public String getTestName() {
         return testName;
     }
+
+    protected void updateReplacement(ObjectNode matchNode) {
+        matchNode.remove(requiredChildKey());
+        matchNode.set(getNewChildKey(), replacementNode.toJsonNode());
+    }
+
 }

+ 44 - 0
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/SerializableJsonNode.java

@@ -0,0 +1,44 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the "Elastic License
+ * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+package org.elasticsearch.gradle.internal.test.rest.transform;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+
+import java.io.Serializable;
+
+/**
+ * A serializable wrapper for a JsonNode that can be used as Gradle task inputs.
+ * This is necessary because JsonNode serialization is not supported by Gradle configuration cache
+ * as it relies on DataInput.readFully which is unsupported by Gradle.
+ *
+ * @param <T> The type of JsonNode this wrapper will hold.
+ */
+public class SerializableJsonNode<T extends JsonNode> implements Serializable {
+
+    private Object value;
+    private Class<? extends JsonNode> type;
+
+    SerializableJsonNode(Object value, Class<? extends JsonNode> type) {
+        this.value = value;
+        this.type = type;
+    }
+
+    public static SerializableJsonNode of(Object value, Class<? extends JsonNode> type) {
+        return new SerializableJsonNode(value, type);
+    }
+
+    public T toJsonNode() {
+        YAMLFactory YAML_FACTORY = new YAMLFactory();
+        ObjectMapper MAPPER = new ObjectMapper(YAML_FACTORY);
+        return (T) MAPPER.convertValue(value, type);
+    }
+}

+ 5 - 5
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/length/ReplaceValueInLength.java

@@ -9,10 +9,10 @@
 
 package org.elasticsearch.gradle.internal.test.rest.transform.length;
 
-import com.fasterxml.jackson.databind.node.NumericNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 
 import org.elasticsearch.gradle.internal.test.rest.transform.ReplaceByKey;
+import org.elasticsearch.gradle.internal.test.rest.transform.SerializableJsonNode;
 import org.gradle.api.tasks.Internal;
 
 /**
@@ -21,11 +21,11 @@ import org.gradle.api.tasks.Internal;
  */
 public class ReplaceValueInLength extends ReplaceByKey {
 
-    public ReplaceValueInLength(String replaceKey, NumericNode replacementNode) {
+    public ReplaceValueInLength(String replaceKey, SerializableJsonNode replacementNode) {
         this(replaceKey, replacementNode, null);
     }
 
-    public ReplaceValueInLength(String replaceKey, NumericNode replacementNode, String testName) {
+    public ReplaceValueInLength(String replaceKey, SerializableJsonNode replacementNode, String testName) {
         super(replaceKey, replaceKey, replacementNode, testName);
     }
 
@@ -38,7 +38,7 @@ public class ReplaceValueInLength extends ReplaceByKey {
     @Override
     public void transformTest(ObjectNode matchParent) {
         ObjectNode matchNode = (ObjectNode) matchParent.get(getKeyToFind());
-        matchNode.remove(requiredChildKey());
-        matchNode.set(getNewChildKey(), getReplacementNode());
+        updateReplacement(matchNode);
     }
+
 }

+ 5 - 4
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/match/AddMatch.java

@@ -16,6 +16,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
 
 import org.elasticsearch.gradle.internal.test.rest.transform.RestTestContext;
 import org.elasticsearch.gradle.internal.test.rest.transform.RestTestTransformByParentArray;
+import org.elasticsearch.gradle.internal.test.rest.transform.SerializableJsonNode;
 import org.gradle.api.tasks.Input;
 import org.gradle.api.tasks.Internal;
 
@@ -28,9 +29,9 @@ public class AddMatch implements RestTestTransformByParentArray {
     private static JsonNodeFactory jsonNodeFactory = JsonNodeFactory.withExactBigDecimals(false);
     private final String matchKey;
     private final String testName;
-    private final JsonNode matchValue;
+    private final SerializableJsonNode<JsonNode> matchValue;
 
-    public AddMatch(String matchKey, JsonNode matchValue, String testName) {
+    public AddMatch(String matchKey, SerializableJsonNode<JsonNode> matchValue, String testName) {
         this.matchKey = matchKey;
         this.matchValue = matchValue;
         this.testName = Objects.requireNonNull(testName, "adding matches is only supported for named tests");
@@ -45,7 +46,7 @@ public class AddMatch implements RestTestTransformByParentArray {
     public void transformTest(ArrayNode matchParent) {
         ObjectNode matchObject = new ObjectNode(jsonNodeFactory);
         ObjectNode matchContent = new ObjectNode(jsonNodeFactory);
-        matchContent.set(matchKey, matchValue);
+        matchContent.set(matchKey, matchValue.toJsonNode());
         matchObject.set("match", matchContent);
         matchParent.add(matchObject);
     }
@@ -70,6 +71,6 @@ public class AddMatch implements RestTestTransformByParentArray {
 
     @Input
     public JsonNode getMatchValue() {
-        return matchValue;
+        return matchValue.toJsonNode();
     }
 }

+ 4 - 4
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/match/ReplaceValueInMatch.java

@@ -13,6 +13,7 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 
 import org.elasticsearch.gradle.internal.test.rest.transform.ReplaceByKey;
+import org.elasticsearch.gradle.internal.test.rest.transform.SerializableJsonNode;
 import org.gradle.api.tasks.Internal;
 
 /**
@@ -20,11 +21,11 @@ import org.gradle.api.tasks.Internal;
  */
 public class ReplaceValueInMatch extends ReplaceByKey {
 
-    public ReplaceValueInMatch(String replaceKey, JsonNode replacementNode) {
+    public ReplaceValueInMatch(String replaceKey, SerializableJsonNode<JsonNode> replacementNode) {
         this(replaceKey, replacementNode, null);
     }
 
-    public ReplaceValueInMatch(String replaceKey, JsonNode replacementNode, String testName) {
+    public ReplaceValueInMatch(String replaceKey, SerializableJsonNode<JsonNode> replacementNode, String testName) {
         super(replaceKey, replaceKey, replacementNode, testName);
     }
 
@@ -37,7 +38,6 @@ public class ReplaceValueInMatch extends ReplaceByKey {
     @Override
     public void transformTest(ObjectNode matchParent) {
         ObjectNode matchNode = (ObjectNode) matchParent.get(getKeyToFind());
-        matchNode.remove(requiredChildKey());
-        matchNode.set(getNewChildKey(), getReplacementNode());
+        updateReplacement(matchNode);
     }
 }

+ 4 - 2
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/text/ReplaceIsFalse.java

@@ -11,12 +11,14 @@ package org.elasticsearch.gradle.internal.test.rest.transform.text;
 
 import com.fasterxml.jackson.databind.node.TextNode;
 
+import org.elasticsearch.gradle.internal.test.rest.transform.SerializableJsonNode;
+
 public class ReplaceIsFalse extends ReplaceTextual {
-    public ReplaceIsFalse(String valueToBeReplaced, TextNode replacementNode) {
+    public ReplaceIsFalse(String valueToBeReplaced, SerializableJsonNode<TextNode> replacementNode) {
         super("is_false", valueToBeReplaced, replacementNode);
     }
 
-    public ReplaceIsFalse(String valueToBeReplaced, TextNode replacementNode, String testName) {
+    public ReplaceIsFalse(String valueToBeReplaced, SerializableJsonNode<TextNode> replacementNode, String testName) {
         super("is_false", valueToBeReplaced, replacementNode, testName);
     }
 }

+ 3 - 1
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/text/ReplaceIsTrue.java

@@ -11,8 +11,10 @@ package org.elasticsearch.gradle.internal.test.rest.transform.text;
 
 import com.fasterxml.jackson.databind.node.TextNode;
 
+import org.elasticsearch.gradle.internal.test.rest.transform.SerializableJsonNode;
+
 public class ReplaceIsTrue extends ReplaceTextual {
-    public ReplaceIsTrue(String valueToBeReplaced, TextNode replacementNode) {
+    public ReplaceIsTrue(String valueToBeReplaced, SerializableJsonNode<TextNode> replacementNode) {
         super("is_true", valueToBeReplaced, replacementNode);
     }
 }

+ 11 - 5
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/transform/text/ReplaceTextual.java

@@ -15,6 +15,7 @@ import com.fasterxml.jackson.databind.node.TextNode;
 
 import org.elasticsearch.gradle.internal.test.rest.transform.RestTestContext;
 import org.elasticsearch.gradle.internal.test.rest.transform.RestTestTransformByParentObject;
+import org.elasticsearch.gradle.internal.test.rest.transform.SerializableJsonNode;
 import org.gradle.api.tasks.Input;
 import org.gradle.api.tasks.Internal;
 import org.gradle.api.tasks.Optional;
@@ -25,17 +26,22 @@ import org.gradle.api.tasks.Optional;
 public class ReplaceTextual implements RestTestTransformByParentObject {
     private final String keyToReplaceName;
     private final String valueToBeReplaced;
-    private final TextNode replacementNode;
+    private final SerializableJsonNode<TextNode> replacementNode;
     private final String testName;
 
-    public ReplaceTextual(String keyToReplaceName, String valueToBeReplaced, TextNode replacementNode) {
+    public ReplaceTextual(String keyToReplaceName, String valueToBeReplaced, SerializableJsonNode<TextNode> replacementNode) {
         this.keyToReplaceName = keyToReplaceName;
         this.valueToBeReplaced = valueToBeReplaced;
         this.replacementNode = replacementNode;
         this.testName = null;
     }
 
-    public ReplaceTextual(String keyToReplaceName, String valueToBeReplaced, TextNode replacementNode, String testName) {
+    public ReplaceTextual(
+        String keyToReplaceName,
+        String valueToBeReplaced,
+        SerializableJsonNode<TextNode> replacementNode,
+        String testName
+    ) {
         this.keyToReplaceName = keyToReplaceName;
         this.valueToBeReplaced = valueToBeReplaced;
         this.replacementNode = replacementNode;
@@ -60,7 +66,7 @@ public class ReplaceTextual implements RestTestTransformByParentObject {
 
     @Override
     public void transformTest(ObjectNode matchParent) {
-        matchParent.set(getKeyToFind(), replacementNode);
+        matchParent.set(getKeyToFind(), replacementNode.toJsonNode());
     }
 
     @Input
@@ -69,7 +75,7 @@ public class ReplaceTextual implements RestTestTransformByParentObject {
     }
 
     @Input
-    public JsonNode getReplacementNode() {
+    public SerializableJsonNode<TextNode> getReplacementNode() {
         return replacementNode;
     }
 

+ 1 - 1
build-tools-internal/src/main/resources/minimumGradleVersion

@@ -1 +1 @@
-8.14.1
+9.0.0

+ 2 - 2
build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/UpdateVersionsTaskTests.java

@@ -189,7 +189,7 @@ public class UpdateVersionsTaskTests {
 
         // write out & parse back in again
         StringWriter writer = new StringWriter();
-        LexicalPreservingPrinter.print(unit, writer);
+        writer.append(LexicalPreservingPrinter.print(unit));
         unit = StaticJavaParser.parse(writer.toString());
 
         // a field has been added
@@ -229,7 +229,7 @@ public class UpdateVersionsTaskTests {
 
         // write out & parse back in again
         StringWriter writer = new StringWriter();
-        LexicalPreservingPrinter.print(unit, writer);
+        writer.append(LexicalPreservingPrinter.print(unit));
         unit = StaticJavaParser.parse(writer.toString());
 
         // a field has been removed

+ 2 - 1
build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/test/rest/transform/length/ReplaceValueInLengthTests.java

@@ -15,6 +15,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
 
 import org.elasticsearch.gradle.internal.test.rest.transform.AssertObjectNodes;
+import org.elasticsearch.gradle.internal.test.rest.transform.SerializableJsonNode;
 import org.elasticsearch.gradle.internal.test.rest.transform.TransformTests;
 import org.junit.Test;
 
@@ -34,7 +35,7 @@ public class ReplaceValueInLengthTests extends TransformTests {
         String test_transformed = "/rest/transform/length/length_replace_transformed_value.yml";
         List<ObjectNode> expectedTransformation = getTests(test_transformed);
 
-        NumericNode replacementNode = MAPPER.convertValue(99, NumericNode.class);
+        var replacementNode = SerializableJsonNode.of(99, NumericNode.class);
 
         List<ObjectNode> transformedTests = transformTests(
             tests,

+ 3 - 2
build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/test/rest/transform/match/AddMatchTests.java

@@ -15,6 +15,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
 
+import org.elasticsearch.gradle.internal.test.rest.transform.SerializableJsonNode;
 import org.elasticsearch.gradle.internal.test.rest.transform.TransformTests;
 import org.hamcrest.CoreMatchers;
 import org.junit.Test;
@@ -38,7 +39,7 @@ public class AddMatchTests extends TransformTests {
     public void testAddAllNotSupported() throws Exception {
         String testName = "/rest/transform/match/match_original.yml";
         List<ObjectNode> tests = getTests(testName);
-        JsonNode addNode = MAPPER.convertValue("_doc", JsonNode.class);
+        var addNode = SerializableJsonNode.of("_doc", JsonNode.class);
         assertEquals(
             "adding matches is only supported for named tests",
             assertThrows(
@@ -52,7 +53,7 @@ public class AddMatchTests extends TransformTests {
     public void testAddByTest() throws Exception {
         String testName = "/rest/transform/match/match_original.yml";
         List<ObjectNode> tests = getTests(testName);
-        JsonNode addNode = MAPPER.convertValue(123456789, JsonNode.class);
+        var addNode = SerializableJsonNode.of(123456789, JsonNode.class);
         validateTest(tests, true);
         List<ObjectNode> transformedTests = transformTests(
             tests,

+ 2 - 1
build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/test/rest/transform/match/ReplaceValueInMatchTests.java

@@ -15,6 +15,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
 
 import org.elasticsearch.gradle.internal.test.rest.transform.AssertObjectNodes;
+import org.elasticsearch.gradle.internal.test.rest.transform.SerializableJsonNode;
 import org.elasticsearch.gradle.internal.test.rest.transform.TransformTests;
 import org.junit.Test;
 
@@ -33,7 +34,7 @@ public class ReplaceValueInMatchTests extends TransformTests {
         String test_transformed = "/rest/transform/match/match_transformed.yml";
         List<ObjectNode> expectedTransformation = getTests(test_transformed);
 
-        JsonNode replacementNode = MAPPER.convertValue("_replaced_type", JsonNode.class);
+        SerializableJsonNode<JsonNode> replacementNode = SerializableJsonNode.of("_replaced_type", JsonNode.class);
         List<ObjectNode> transformedTests = transformTests(
             tests,
             List.of(

+ 4 - 9
build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/test/rest/transform/text/ReplaceTextualTests.java

@@ -9,22 +9,17 @@
 
 package org.elasticsearch.gradle.internal.test.rest.transform.text;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.fasterxml.jackson.databind.node.TextNode;
-import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
 
 import org.elasticsearch.gradle.internal.test.rest.transform.AssertObjectNodes;
+import org.elasticsearch.gradle.internal.test.rest.transform.SerializableJsonNode;
 import org.elasticsearch.gradle.internal.test.rest.transform.TransformTests;
 import org.junit.Test;
 
 import java.util.List;
 
 public class ReplaceTextualTests extends TransformTests {
-
-    private static final YAMLFactory YAML_FACTORY = new YAMLFactory();
-    private static final ObjectMapper MAPPER = new ObjectMapper(YAML_FACTORY);
-
     @Test
     public void testReplaceAll() throws Exception {
         String test_original = "/rest/transform/text/text_replace_original.yml";
@@ -36,9 +31,9 @@ public class ReplaceTextualTests extends TransformTests {
         List<ObjectNode> transformedTests = transformTests(
             tests,
             List.of(
-                new ReplaceTextual("key_to_replace", "value_to_replace", MAPPER.convertValue("_replaced_value", TextNode.class), null),
-                new ReplaceIsTrue("is_true_to_replace", MAPPER.convertValue("is_true_replaced", TextNode.class)),
-                new ReplaceIsFalse("is_false_to_replace", MAPPER.convertValue("is_false_replaced", TextNode.class))
+                new ReplaceTextual("key_to_replace", "value_to_replace", SerializableJsonNode.of("_replaced_value", TextNode.class), null),
+                new ReplaceIsTrue("is_true_to_replace", SerializableJsonNode.of("is_true_replaced", TextNode.class)),
+                new ReplaceIsFalse("is_false_to_replace", SerializableJsonNode.of("is_false_replaced", TextNode.class))
             )
         );
 

+ 2 - 1
build-tools/src/testFixtures/groovy/org/elasticsearch/gradle/fixtures/AbstractGradleFuncTest.groovy

@@ -83,7 +83,8 @@ abstract class AbstractGradleFuncTest extends Specification {
         if (subProjectBuild.exists() == false) {
             settingsFile << "include \"${subProjectPath}\"\n"
         }
-        subProjectBuild
+        subProjectBuild.parentFile.mkdirs()
+        return subProjectBuild
     }
 
     File subProject(String subProjectPath, Closure configAction) {

+ 2 - 0
build.gradle

@@ -22,6 +22,8 @@ import org.gradle.plugins.ide.eclipse.model.AccessRule
 import org.gradle.plugins.ide.eclipse.model.ProjectDependency
 import org.elasticsearch.gradle.DistributionDownloadPlugin
 
+import groovy.xml.XmlParser;
+import groovy.xml.XmlNodePrinter;
 import java.nio.file.Files
 
 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING

+ 3 - 0
distribution/docker/build.gradle

@@ -195,6 +195,9 @@ ext.dockerBuildContext = { Architecture architecture, DockerBase base ->
       }
     } else {
       into('bin') {
+        filePermissions {
+          unix(0755)
+        }
         from projectDir.resolve("src/docker/bin")
       }
 

+ 2 - 2
gradle/build.versions.toml

@@ -2,7 +2,7 @@
 asm = "9.7.1"
 jackson = "2.15.0"
 junit5 = "5.12.1"
-spock = "2.1-groovy-3.0"
+spock = "2.3-groovy-4.0"
 nmcp = "0.1.5"
 
 [libraries]
@@ -22,7 +22,7 @@ hamcrest = "org.hamcrest:hamcrest:3.0"
 httpcore5 = "org.apache.httpcomponents.core5:httpcore5:5.3.3"
 httpclient5 = "org.apache.httpcomponents.client5:httpclient5:5.4.2"
 idea-ext = "gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:1.1.4"
-javaparser = "com.github.javaparser:javaparser-core:3.18.0"
+javaparser = "com.github.javaparser:javaparser-core:3.27.0"
 json-schema-validator = "com.networknt:json-schema-validator:1.0.72"
 json-assert = "org.skyscreamer:jsonassert:1.5.0"
 jackson-core = { group = "com.fasterxml.jackson.core", name="jackson-core", version.ref="jackson" }

+ 22 - 12
gradle/verification-metadata.xml

@@ -472,6 +472,11 @@
             <sha256 value="df7e2d5b8319efd51d015ab5071a271f8463158bc2f0979d05393fe028d856a0" origin="Generated by Gradle"/>
          </artifact>
       </component>
+      <component group="com.github.javaparser" name="javaparser-core" version="3.27.0">
+         <artifact name="javaparser-core-3.27.0.jar">
+            <sha256 value="11b0deeaeb29f2496e1704c8c6f7593f14901f7253a671b81bdaa531bead779f" origin="Generated by Gradle"/>
+         </artifact>
+      </component>
       <component group="com.github.johnrengelman" name="shadow" version="8.1.1">
          <artifact name="shadow-8.1.1.jar">
             <sha256 value="084197555590a53bb21b59508a3330559f536ddb448eafd1ec675f5462036fcf" origin="Generated by Gradle"/>
@@ -2456,6 +2461,11 @@
             <sha256 value="0070a12e58f491b95719391325299a6294530ee6c3ce25e50bdc98b0b700966c" origin="Generated by Gradle"/>
          </artifact>
       </component>
+      <component group="org.apache.groovy" name="groovy" version="4.0.4">
+         <artifact name="groovy-4.0.4.jar">
+            <sha256 value="1429a3d4cd6f5d7858e4941e553e0bb4b7bc451c003050b9694213eda0614d04" origin="Generated by Gradle"/>
+         </artifact>
+      </component>
       <component group="org.apache.hadoop" name="hadoop-annotations" version="2.8.5">
          <artifact name="hadoop-annotations-2.8.5.jar">
             <sha256 value="6df69a714d6ed71842004733724add3a5e7d1078f1e0a66631b4f6b56118875b" origin="Generated by Gradle"/>
@@ -4227,9 +4237,9 @@
             <sha256 value="c316163581aaa5649280122b12ea36fe4e9c202a1a2267753fea7c9e1df055eb" origin="Generated by Gradle"/>
          </artifact>
       </component>
-      <component group="org.junit.platform" name="junit-platform-commons" version="1.8.1">
-         <artifact name="junit-platform-commons-1.8.1.jar">
-            <sha256 value="fa4fa68c8bd54dd0cb49c3fcbe9b2e42f4da6bedbe7e7ccf2a05f1a1e609b593" origin="Generated by Gradle"/>
+      <component group="org.junit.platform" name="junit-platform-commons" version="1.9.0">
+         <artifact name="junit-platform-commons-1.9.0.jar">
+            <sha256 value="e5894b710094b4caafc6280b8829a439fb764901ea0ae18d06ed80388b309b7a" origin="Generated by Gradle"/>
          </artifact>
       </component>
       <component group="org.junit.platform" name="junit-platform-engine" version="1.12.1">
@@ -4237,9 +4247,9 @@
             <sha256 value="7fedff93fd92aec7d29fc60dc01fa027246b36b8088423a5efc4949e5f6affa4" origin="Generated by Gradle"/>
          </artifact>
       </component>
-      <component group="org.junit.platform" name="junit-platform-engine" version="1.8.1">
-         <artifact name="junit-platform-engine-1.8.1.jar">
-            <sha256 value="702868ed7e86b9b4672ede0f1e185e905baca9afab57746a7c650be3c7bca047" origin="Generated by Gradle"/>
+      <component group="org.junit.platform" name="junit-platform-engine" version="1.9.0">
+         <artifact name="junit-platform-engine-1.9.0.jar">
+            <sha256 value="aaec735f7444a9fc055e206598de3d829c24e9c7a8eea6efdeeb1962087fe811" origin="Generated by Gradle"/>
          </artifact>
       </component>
       <component group="org.junit.platform" name="junit-platform-launcher" version="1.12.1">
@@ -4827,14 +4837,14 @@
             <sha256 value="42e1dfb26becbf1a633f25b47e39fcc422b85e77e4c0468d9a44f885f5fa0be2" origin="Generated by Gradle"/>
          </artifact>
       </component>
-      <component group="org.spockframework" name="spock-core" version="2.1-groovy-3.0">
-         <artifact name="spock-core-2.1-groovy-3.0.jar">
-            <sha256 value="fa8ff7446df04c51b3ccbc2a1bbc71f9c280878afe2d53be44d59d00b1b9828c" origin="Generated by Gradle"/>
+      <component group="org.spockframework" name="spock-core" version="2.3-groovy-4.0">
+         <artifact name="spock-core-2.3-groovy-4.0.jar">
+            <sha256 value="60a614a7640c4fc9dfd432929a426bd0448f299915924556ae372105a118ff14" origin="Generated by Gradle"/>
          </artifact>
       </component>
-      <component group="org.spockframework" name="spock-junit4" version="2.1-groovy-3.0">
-         <artifact name="spock-junit4-2.1-groovy-3.0.jar">
-            <sha256 value="6e6d05ead831c37e6fc93415cdaea60656674266a5574c98a0e1f7a82b990ca2" origin="Generated by Gradle"/>
+      <component group="org.spockframework" name="spock-junit4" version="2.3-groovy-4.0">
+         <artifact name="spock-junit4-2.3-groovy-4.0.jar">
+            <sha256 value="fea4b91afb5eb68a80007c9d88c8c189b5cd791d39d601d75c92e6f6bb587735" origin="Generated by Gradle"/>
          </artifact>
       </component>
       <component group="org.subethamail" name="subethasmtp" version="3.1.7">

+ 2 - 2
gradle/wrapper/gradle-wrapper.properties

@@ -1,7 +1,7 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionSha256Sum=443c9c8ee2ac1ee0e11881a40f2376d79c66386264a44b24a9f8ca67e633375f
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-all.zip
+distributionSha256Sum=f759b8dd5204e2e3fa4ca3e73f452f087153cf81bac9561eeb854229cc2c5365
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-all.zip
 networkTimeout=10000
 validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME

+ 2 - 2
plugins/examples/gradle/wrapper/gradle-wrapper.properties

@@ -1,7 +1,7 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionSha256Sum=443c9c8ee2ac1ee0e11881a40f2376d79c66386264a44b24a9f8ca67e633375f
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-all.zip
+distributionSha256Sum=f759b8dd5204e2e3fa4ca3e73f452f087153cf81bac9561eeb854229cc2c5365
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-all.zip
 networkTimeout=10000
 validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME