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

amaechler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new bd61838ac04 Add the Maven wrapper and use it in CI (#20496)
bd61838ac04 is described below

commit bd61838ac04e2f6f42342340c49de2083c9142f8
Author: Andreas Maechler <[email protected]>
AuthorDate: Wed Oct 7 10:49:35 2026 -0600

    Add the Maven wrapper and use it in CI (#20496)
    
    Pin Maven 3.10.0 with the Maven wrapper so CI no longer changes Maven
    version when the runner image updates. CI scripts and workflows call
    ./mvnw instead of mvn. Register the wrapper scripts from Apache Maven
    Wrapper in LICENSE, NOTICE and licenses.yaml.
---
 .github/scripts/analyze_dependencies_script.sh   |   2 +-
 .github/scripts/create-jacoco-coverage-report.sh |   8 +-
 .github/scripts/license_checks_script.sh         |   2 +-
 .github/scripts/openrewrite.sh                   |   4 +-
 .github/scripts/packaging-check.sh               |   4 +-
 .github/scripts/run_docker-tests                 |   2 +-
 .github/scripts/run_unit-tests                   |   2 +-
 .github/scripts/static-checks-maven.sh           |  16 +-
 .github/scripts/strict-compilation.sh            |   2 +-
 .github/scripts/web-checks.sh                    |   4 +-
 .github/workflows/codeql.yml                     |   2 +-
 .github/workflows/cron-job-its.yml               |   6 +-
 .github/workflows/docker-tests.yml               |   2 +-
 .github/workflows/worker.yml                     |   2 +-
 .mvn/wrapper/maven-wrapper.properties            |   4 +
 LICENSE                                          |   4 +
 NOTICE                                           |  12 +
 docs/development/build.md                        |   2 +-
 licenses.yaml                                    |  21 ++
 mvnw                                             | 295 +++++++++++++++++++++++
 mvnw.cmd                                         | 189 +++++++++++++++
 21 files changed, 555 insertions(+), 30 deletions(-)

diff --git a/.github/scripts/analyze_dependencies_script.sh 
b/.github/scripts/analyze_dependencies_script.sh
index 9da6c05d778..5cc3894ea46 100755
--- a/.github/scripts/analyze_dependencies_script.sh
+++ b/.github/scripts/analyze_dependencies_script.sh
@@ -15,7 +15,7 @@
 
 #!bin/bash
 
-mvn -B dependency:analyze -DoutputXML=true -DignoreNonCompile=true 
-DfailOnWarning=true ||
+./mvnw -B dependency:analyze -DoutputXML=true -DignoreNonCompile=true 
-DfailOnWarning=true ||
 { echo "
     The dependency analysis has found a dependency that is either:
 
diff --git a/.github/scripts/create-jacoco-coverage-report.sh 
b/.github/scripts/create-jacoco-coverage-report.sh
index 8acbcb67e2b..73ac69cefe6 100755
--- a/.github/scripts/create-jacoco-coverage-report.sh
+++ b/.github/scripts/create-jacoco-coverage-report.sh
@@ -25,12 +25,12 @@ git remote set-branches --add origin ${GITHUB_BASE_REF}
 git fetch
 
 # Compile the project. jacoco:report needs class files along with jacoco.exec 
files to generate the report.
-mvn -B install -DskipTests -P skip-static-checks -Dweb.console.skip=true 
-Dmaven.javadoc.skip=true
+./mvnw -B install -DskipTests -P skip-static-checks -Dweb.console.skip=true 
-Dmaven.javadoc.skip=true
 
 # If there are multiple jacoco.exec files present in any module, merge them 
into a single jacoco.exec file for that module.
-mvn jacoco:merge
+./mvnw jacoco:merge
 
-mvn jacoco:report
+./mvnw jacoco:report
 
 changed_files="$(git diff --name-only origin/${GITHUB_BASE_REF}...HEAD 
'**/*.java' || [[ $? == 1 ]])"
 
@@ -40,7 +40,7 @@ do
   echo $f
 done
 
-mvn 
com.github.eirslett:frontend-maven-plugin:install-node-and-npm@install-node-and-npm
 -pl web-console/
+./mvnw 
com.github.eirslett:frontend-maven-plugin:install-node-and-npm@install-node-and-npm
 -pl web-console/
 PATH+=:web-console/target/node/
 npm install @connectis/[email protected]
 
diff --git a/.github/scripts/license_checks_script.sh 
b/.github/scripts/license_checks_script.sh
index e278fb4a7fa..168b616750e 100755
--- a/.github/scripts/license_checks_script.sh
+++ b/.github/scripts/license_checks_script.sh
@@ -18,7 +18,7 @@
 set -e
 
 ./.github/scripts/setup_generate_license.sh
-mvn -B apache-rat:check -Prat --fail-at-end \
+./mvnw -B apache-rat:check -Prat --fail-at-end \
 
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
 \
 -Drat.consoleOutput=true
 # Generate dependency reports and checks they are valid.
diff --git a/.github/scripts/openrewrite.sh b/.github/scripts/openrewrite.sh
index 587601267c3..c0ab967ea55 100755
--- a/.github/scripts/openrewrite.sh
+++ b/.github/scripts/openrewrite.sh
@@ -21,6 +21,6 @@ set -x
 export MAVEN_OPTS=-Xmx8g
 
 echo 'Running Maven install...'
-mvn -B clean install -q -ff -pl '!distribution' -P skip-tests 
-Dweb.console.skip=true -T1C
+./mvnw -B clean install -q -ff -pl '!distribution' -P skip-tests 
-Dweb.console.skip=true -T1C
 
-mvn -B rewrite:dryRun -Dweb.console.skip=true
+./mvnw -B rewrite:dryRun -Dweb.console.skip=true
diff --git a/.github/scripts/packaging-check.sh 
b/.github/scripts/packaging-check.sh
index 6952b891bd3..caebb66870e 100755
--- a/.github/scripts/packaging-check.sh
+++ b/.github/scripts/packaging-check.sh
@@ -25,9 +25,9 @@ set -x
 # profile is enabled here so that the Docker test job only needs to build the
 # binary tarball. GPG signing and the OWASP dependency check are skipped as 
they
 # are not meaningful in CI.
-mvn -B clean install -Prat -Papache-release --fail-at-end \
+./mvnw -B clean install -Prat -Papache-release --fail-at-end \
   -pl '!benchmarks, !distribution' -P skip-tests -Dweb.console.skip=false -T1C 
\
   -Dgpg.skip -Ddependency-check.skip
-mvn -B install -Prat -Papache-release -Pdist -Pbundle-contrib-exts 
--fail-at-end \
+./mvnw -B install -Prat -Papache-release -Pdist -Pbundle-contrib-exts 
--fail-at-end \
   -pl 'distribution' -P skip-tests -Dweb.console.skip=false -T1C \
   -Dgpg.skip -Ddependency-check.skip
diff --git a/.github/scripts/run_docker-tests b/.github/scripts/run_docker-tests
index 4ce8a6c0fe8..d0895081697 100755
--- a/.github/scripts/run_docker-tests
+++ b/.github/scripts/run_docker-tests
@@ -41,4 +41,4 @@ OPTS+=" -nsu"
 # local Maven repository on a fresh runner, and no Maven build cache is 
persisted
 # across jobs. Adding -am would re-run the whole reactor, including 
web-console,
 # a second time.
-mvn -B -pl embedded-tests $OPTS verify -Pdocker-tests,skip-static-checks 
-DskipUTs -D$DRUID_IMAGE_SYS_PROPERTY=$DRUID_IMAGE_NAME 
"-DjfrProfilerArgLine=$JFR_PROFILER_ARG_LINE" "$@"
+./mvnw -B -pl embedded-tests $OPTS verify -Pdocker-tests,skip-static-checks 
-DskipUTs -D$DRUID_IMAGE_SYS_PROPERTY=$DRUID_IMAGE_NAME 
"-DjfrProfilerArgLine=$JFR_PROFILER_ARG_LINE" "$@"
diff --git a/.github/scripts/run_unit-tests b/.github/scripts/run_unit-tests
index df685a54c52..f2c5ac87e3e 100755
--- a/.github/scripts/run_unit-tests
+++ b/.github/scripts/run_unit-tests
@@ -21,4 +21,4 @@ set -x
 OPTS+=" -Dsurefire.failIfNoSpecifiedTests=false -P skip-static-checks 
-Dweb.console.skip=true"
 OPTS+=" -Djacoco.destFile=target/jacoco-${HASH}.exec"
 
-mvn -B $OPTS test "-DjfrProfilerArgLine=$JFR_PROFILER_ARG_LINE" "$@"
+./mvnw -B $OPTS test "-DjfrProfilerArgLine=$JFR_PROFILER_ARG_LINE" "$@"
diff --git a/.github/scripts/static-checks-maven.sh 
b/.github/scripts/static-checks-maven.sh
index 81a79853954..adca96c10b0 100755
--- a/.github/scripts/static-checks-maven.sh
+++ b/.github/scripts/static-checks-maven.sh
@@ -19,13 +19,13 @@ set -e
 set -x
 
 echo 'Running Maven install...'
-mvn -B clean install -q -ff -pl '!distribution' -P skip-tests 
-Dweb.console.skip=true -Dmaven.javadoc.skip=true -T1C
+./mvnw -B clean install -q -ff -pl '!distribution' -P skip-tests 
-Dweb.console.skip=true -Dmaven.javadoc.skip=true -T1C
 
-mvn -B checkstyle:checkstyle --fail-at-end
+./mvnw -B checkstyle:checkstyle --fail-at-end
 
 # Repo-wide RAT check. packaging-check also runs RAT, but it excludes the
 # benchmarks module from its reactor, so keep this standalone pass here.
-mvn -B apache-rat:check -Prat --fail-at-end \
+./mvnw -B apache-rat:check -Prat --fail-at-end \
   
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
 \
   -Drat.consoleOutput=true
 
@@ -36,13 +36,13 @@ mvn -B apache-rat:check -Prat --fail-at-end \
 
 ./.github/scripts/analyze_dependencies_script.sh
 
-mvn -B animal-sniffer:check --fail-at-end
+./mvnw -B animal-sniffer:check --fail-at-end
 
-mvn -B enforcer:enforce --fail-at-end
+./mvnw -B enforcer:enforce --fail-at-end
 
-mvn -B forbiddenapis:check forbiddenapis:testCheck --fail-at-end
+./mvnw -B forbiddenapis:check forbiddenapis:testCheck --fail-at-end
 
 # TODO: consider adding pmd:cpd-check
-mvn -B pmd:check --fail-at-end
+./mvnw -B pmd:check --fail-at-end
 
-mvn -B spotbugs:check --fail-at-end -pl '!benchmarks'
+./mvnw -B spotbugs:check --fail-at-end -pl '!benchmarks'
diff --git a/.github/scripts/strict-compilation.sh 
b/.github/scripts/strict-compilation.sh
index f06a0e8713c..ab6cc40420c 100755
--- a/.github/scripts/strict-compilation.sh
+++ b/.github/scripts/strict-compilation.sh
@@ -18,4 +18,4 @@
 set -e
 set -x
 
-mvn -B clean -DstrictCompile test-compile --fail-at-end -P skip-tests 
-Dweb.console.skip=true -T1C
+./mvnw -B clean -DstrictCompile test-compile --fail-at-end -P skip-tests 
-Dweb.console.skip=true -T1C
diff --git a/.github/scripts/web-checks.sh b/.github/scripts/web-checks.sh
index 2c01dbf941e..8f39c16a47f 100755
--- a/.github/scripts/web-checks.sh
+++ b/.github/scripts/web-checks.sh
@@ -19,7 +19,7 @@ set -e
 set -x
 
 # Install node.js via maven frontend plugin (same approach as jacoco script)
-mvn -B 
com.github.eirslett:frontend-maven-plugin:install-node-and-npm@install-node-and-npm
 -pl web-console/
+./mvnw -B 
com.github.eirslett:frontend-maven-plugin:install-node-and-npm@install-node-and-npm
 -pl web-console/
 PATH+=:web-console/target/node/
 
 # docs
@@ -31,7 +31,7 @@ npm run spellcheck
 cd ..
 
 # web console
-mvn -B test -pl 'web-console'
+./mvnw -B test -pl 'web-console'
 
 # web console end-to-end test
 ./.github/scripts/setup_generate_license.sh
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 52d36374fa1..90d4b8ccc78 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -68,7 +68,7 @@ jobs:
       if: ${{ matrix.language == 'java' }}
       run: |
         echo "Building using custom commands"
-        mvn clean package -f "pom.xml" -B -V -e -Dfindbugs.skip 
-Dcheckstyle.skip -Dpmd.skip=true -Denforcer.skip -Dmaven.javadoc.skip 
-DskipTests -Dmaven.test.skip.exec -Dlicense.skip=true -Dweb.console.skip=true 
-Dcyclonedx.skip=true
+        ./mvnw clean package -f "pom.xml" -B -V -e -Dfindbugs.skip 
-Dcheckstyle.skip -Dpmd.skip=true -Denforcer.skip -Dmaven.javadoc.skip 
-DskipTests -Dmaven.test.skip.exec -Dlicense.skip=true -Dweb.console.skip=true 
-Dcyclonedx.skip=true
 
     # â„šī¸ Command-line programs to run using the OS shell.
     # 📚 See 
https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
diff --git a/.github/workflows/cron-job-its.yml 
b/.github/workflows/cron-job-its.yml
index 15c6f7634df..7fc53700f6f 100644
--- a/.github/workflows/cron-job-its.yml
+++ b/.github/workflows/cron-job-its.yml
@@ -46,7 +46,7 @@ jobs:
           cache: maven
 
       - name: maven build # needed to rebuild in case of maven snapshot 
resolution fails
-        run: mvn clean install -P dist -P skip-static-checks,skip-tests 
-Dmaven.javadoc.skip=true -Dcyclonedx.skip=true -Dweb.console.skip=true
+        run: ./mvnw clean install -P dist -P skip-static-checks,skip-tests 
-Dmaven.javadoc.skip=true -Dcyclonedx.skip=true -Dweb.console.skip=true
 
       - name: security vulnerabilities check
         env:
@@ -54,10 +54,10 @@ jobs:
           OSS_INDEX_PASSWORD: ${{ secrets.OSS_INDEX_PASSWORD }}
           NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
         run: |
-          mvn -B dependency-check:purge dependency-check:check 
-DnvdApiKey=$NVD_API_KEY -DossIndexUsername=$OSS_INDEX_USERNAME 
-DossIndexPassword=$OSS_INDEX_PASSWORD || { echo "
+          ./mvnw -B dependency-check:purge dependency-check:check 
-DnvdApiKey=$NVD_API_KEY -DossIndexUsername=$OSS_INDEX_USERNAME 
-DossIndexPassword=$OSS_INDEX_PASSWORD || { echo "
           The OWASP dependency check has found security vulnerabilities. 
Please use a newer version
           of the dependency that does not have vulnerabilities. To see a 
report run
-          `mvn dependency-check:check`
+          `./mvnw dependency-check:check`
           If the analysis has false positives,
           they can be suppressed by adding entries to 
owasp-dependency-check-suppressions.xml (for more
           information, see 
https://jeremylong.github.io/DependencyCheck/general/suppression.html).
diff --git a/.github/workflows/docker-tests.yml 
b/.github/workflows/docker-tests.yml
index 2f816bb70fd..7d612c67a54 100644
--- a/.github/workflows/docker-tests.yml
+++ b/.github/workflows/docker-tests.yml
@@ -43,7 +43,7 @@ jobs:
         # depends on it. The web console assets are skipped too: no Docker test
         # uses the console, the router tolerates the missing assets, and the
         # console is fully built and packaged by packaging-check on every 
commit.
-        run: mvn -B -T1C clean install -pl '!benchmarks' 
-Pdist,bundle-contrib-exts,skip-static-checks,skip-tests -Dweb.console.skip=true
+        run: ./mvnw -B -T1C clean install -pl '!benchmarks' 
-Pdist,bundle-contrib-exts,skip-static-checks,skip-tests -Dweb.console.skip=true
       - name: Build the Docker image
         run: |
           set -o pipefail
diff --git a/.github/workflows/worker.yml b/.github/workflows/worker.yml
index 93a6ceed0a2..fa0474460a8 100644
--- a/.github/workflows/worker.yml
+++ b/.github/workflows/worker.yml
@@ -78,7 +78,7 @@ jobs:
         run: |
           set -eu
           for attempt in 1 2 3; do
-            if mvn -B -U -N validate -Pskip-static-checks 
-Dweb.console.skip=true; then
+            if ./mvnw -B -U -N validate -Pskip-static-checks 
-Dweb.console.skip=true; then
               exit 0
             fi
             if [ "$attempt" -eq 3 ]; then
diff --git a/.mvn/wrapper/maven-wrapper.properties 
b/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 00000000000..e193f5bfc6a
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,4 @@
+wrapperVersion=3.3.4
+distributionType=only-script
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.10.0/apache-maven-3.10.0-bin.zip
+distributionSha256Sum=1f6d9909266510f039f59aa0e13dcd2c66da85f043e56276e41f2918f8bddaff
diff --git a/LICENSE b/LICENSE
index 6b3f53421dd..5adaa9c7639 100644
--- a/LICENSE
+++ b/LICENSE
@@ -288,6 +288,10 @@ SOURCE/JAVA-CORE
     This product contains the class copied from 
https://github.com/FasterXML/jackson-databind
       * 
extensions-core/s3-extensions/src/main/java/com/fasterxml/jackson/databind/PropertyNamingStrategies.java
 
+    This product contains the Maven Wrapper scripts from Apache Maven Wrapper.
+      * mvnw
+      * mvnw.cmd
+
 
 
 MIT License
diff --git a/NOTICE b/NOTICE
index 4e3211edfb9..4d84c66cc66 100644
--- a/NOTICE
+++ b/NOTICE
@@ -94,6 +94,18 @@ Copyright 2001-2020 The Apache Software Foundation
 This product includes software developed at
 The Apache Software Foundation (https://www.apache.org/).
 
+================= Apache Maven Wrapper 3.3.4 =================
+
+Apache Maven Wrapper
+Copyright 2013-2022 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+The original idea and initial implementation of the maven-wrapper module is 
derived
+from the Gradle Wrapper which was written originally by Hans Dockter and Adam 
Murdoch.
+Copyright 2007 the original author or authors.
+
 -------------------------------------------------------------------------------
 
 This library contains a modified version of Alessandro Colantonio's CONCISE
diff --git a/docs/development/build.md b/docs/development/build.md
index b7dfb0f805c..609b835f133 100644
--- a/docs/development/build.md
+++ b/docs/development/build.md
@@ -34,7 +34,7 @@ make sure it has `/master/` in the URL.
 ### Installing Java and Maven
 
 - See the [Java documentation](../operations/java.md) for information about 
obtaining a supported JDK
-- [Maven version 3.9 or later](http://maven.apache.org/download.cgi)
+- [Maven version 3.9 or later](http://maven.apache.org/download.cgi), or use 
the Maven wrapper (`./mvnw`) in the repository root, which downloads the Maven 
version that CI uses
 
 ### Other Dependencies
 
diff --git a/licenses.yaml b/licenses.yaml
index ada4e418dbf..25bebaf85b0 100644
--- a/licenses.yaml
+++ b/licenses.yaml
@@ -165,6 +165,27 @@ notice: |
 
 ---
 
+name: Maven Wrapper scripts from Apache Maven Wrapper
+license_category: source
+module: java-core
+license_name: Apache License version 2.0
+version: 3.3.4
+source_paths:
+  - mvnw
+  - mvnw.cmd
+notice: |
+  Apache Maven Wrapper
+  Copyright 2013-2022 The Apache Software Foundation
+
+  This product includes software developed at
+  The Apache Software Foundation (http://www.apache.org/).
+
+  The original idea and initial implementation of the maven-wrapper module is 
derived
+  from the Gradle Wrapper which was written originally by Hans Dockter and 
Adam Murdoch.
+  Copyright 2007 the original author or authors.
+
+---
+
 name: LDAP string encoding function from OWASP ESAPI
 license_category: source
 module: extensions/druid-basic-security
diff --git a/mvnw b/mvnw
new file mode 100755
index 00000000000..bd8896bf221
--- /dev/null
+++ b/mvnw
@@ -0,0 +1,295 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.3.4
+#
+# Optional ENV vars
+# -----------------
+#   JAVA_HOME - location of a JDK home dir, required when download maven via 
java source
+#   MVNW_REPOURL - repo url base for downloading maven distribution
+#   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+#   MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; 
others: silence the output
+# ----------------------------------------------------------------------------
+
+set -euf
+[ "${MVNW_VERBOSE-}" != debug ] || set -x
+
+# OS specific support.
+native_path() { printf %s\\n "$1"; }
+case "$(uname)" in
+CYGWIN* | MINGW*)
+  [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
+  native_path() { cygpath --path --windows "$1"; }
+  ;;
+esac
+
+# set JAVACMD and JAVACCMD
+set_java_home() {
+  # For Cygwin and MinGW, ensure paths are in Unix format before anything is 
touched
+  if [ -n "${JAVA_HOME-}" ]; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ]; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+      JAVACCMD="$JAVA_HOME/jre/sh/javac"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+      JAVACCMD="$JAVA_HOME/bin/javac"
+
+      if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
+        echo "The JAVA_HOME environment variable is not defined correctly, so 
mvnw cannot run." >&2
+        echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" 
or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
+        return 1
+      fi
+    fi
+  else
+    JAVACMD="$(
+      'set' +e
+      'unset' -f command 2>/dev/null
+      'command' -v java
+    )" || :
+    JAVACCMD="$(
+      'set' +e
+      'unset' -f command 2>/dev/null
+      'command' -v javac
+    )" || :
+
+    if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
+      echo "The java/javac command does not exist in PATH nor is JAVA_HOME 
set, so mvnw cannot run." >&2
+      return 1
+    fi
+  fi
+}
+
+# hash string like Java String::hashCode
+hash_string() {
+  str="${1:-}" h=0
+  while [ -n "$str" ]; do
+    char="${str%"${str#?}"}"
+    h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
+    str="${str#?}"
+  done
+  printf %x\\n $h
+}
+
+verbose() { :; }
+[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
+
+die() {
+  printf %s\\n "$1" >&2
+  exit 1
+}
+
+trim() {
+  # MWRAPPER-139:
+  #   Trims trailing and leading whitespace, carriage returns, tabs, and 
linefeeds.
+  #   Needed for removing poorly interpreted newline sequences when running in 
more
+  #   exotic environments such as mingw bash on Windows.
+  printf "%s" "${1}" | tr -d '[:space:]'
+}
+
+scriptDir="$(dirname "$0")"
+scriptName="$(basename "$0")"
+
+# parse distributionUrl and optional distributionSha256Sum, requires 
.mvn/wrapper/maven-wrapper.properties
+while IFS="=" read -r key value; do
+  case "${key-}" in
+  distributionUrl) distributionUrl=$(trim "${value-}") ;;
+  distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
+  esac
+done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
+[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in 
$scriptDir/.mvn/wrapper/maven-wrapper.properties"
+
+case "${distributionUrl##*/}" in
+maven-mvnd-*bin.*)
+  MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
+  case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
+  *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
+  :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
+  :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
+  :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
+  *)
+    echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use 
pure java version" >&2
+    distributionPlatform=linux-amd64
+    ;;
+  esac
+  distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
+  ;;
+maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
+*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
+esac
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: 
~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
+[ -z "${MVNW_REPOURL-}" ] || 
distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
+distributionUrlName="${distributionUrl##*/}"
+distributionUrlNameMain="${distributionUrlName%.*}"
+distributionUrlNameMain="${distributionUrlNameMain%-bin}"
+MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
+MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string
 "$distributionUrl")"
+
+exec_maven() {
+  unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
+  exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec 
$MAVEN_HOME/bin/$MVN_CMD"
+}
+
+if [ -d "$MAVEN_HOME" ]; then
+  verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+  exec_maven "$@"
+fi
+
+case "${distributionUrl-}" in
+*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
+*) die "distributionUrl is not valid, must match *-bin.zip or 
maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
+esac
+
+# prepare tmp dir
+if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
+  clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
+  trap clean HUP INT TERM EXIT
+else
+  die "cannot create temp dir"
+fi
+
+mkdir -p -- "${MAVEN_HOME%/*}"
+
+# Download and Install Apache Maven
+verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+verbose "Downloading from: $distributionUrl"
+verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+# select .zip or .tar.gz
+if ! command -v unzip >/dev/null; then
+  distributionUrl="${distributionUrl%.zip}.tar.gz"
+  distributionUrlName="${distributionUrl##*/}"
+fi
+
+# verbose opt
+__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q 
__MVNW_QUIET_TAR=''
+[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' 
__MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
+
+# normalize http auth
+case "${MVNW_PASSWORD:+has-password}" in
+'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' 
;;
+esac
+
+if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
+  verbose "Found wget ... using wget"
+  wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O 
"$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch 
$distributionUrl"
+elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
+  verbose "Found curl ... using curl"
+  curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o 
"$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: 
Failed to fetch $distributionUrl"
+elif set_java_home; then
+  verbose "Falling back to use Java to download"
+  javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
+  targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
+  cat >"$javaSource" <<-END
+       public class Downloader extends java.net.Authenticator
+       {
+         protected java.net.PasswordAuthentication getPasswordAuthentication()
+         {
+           return new java.net.PasswordAuthentication( System.getenv( 
"MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
+         }
+         public static void main( String[] args ) throws Exception
+         {
+           setDefault( new Downloader() );
+           java.nio.file.Files.copy( java.net.URI.create( args[0] 
).toURL().openStream(), java.nio.file.Paths.get( args[1] 
).toAbsolutePath().normalize() );
+         }
+       }
+       END
+  # For Cygwin/MinGW, switch paths to Windows format before running javac and 
java
+  verbose " - Compiling Downloader.java ..."
+  "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed 
to compile Downloader.java"
+  verbose " - Running Downloader.java ..."
+  "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" 
Downloader "$distributionUrl" "$(native_path "$targetZip")"
+fi
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+if [ -n "${distributionSha256Sum-}" ]; then
+  distributionSha256Result=false
+  if [ "$MVN_CMD" = mvnd.sh ]; then
+    echo "Checksum validation is not supported for maven-mvnd." >&2
+    echo "Please disable validation by removing 'distributionSha256Sum' from 
your maven-wrapper.properties." >&2
+    exit 1
+  elif command -v sha256sum >/dev/null; then
+    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | 
sha256sum -c - >/dev/null 2>&1; then
+      distributionSha256Result=true
+    fi
+  elif command -v shasum >/dev/null; then
+    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | 
shasum -a 256 -c >/dev/null 2>&1; then
+      distributionSha256Result=true
+    fi
+  else
+    echo "Checksum validation was requested but neither 'sha256sum' or 
'shasum' are available." >&2
+    echo "Please install either command, or disable validation by removing 
'distributionSha256Sum' from your maven-wrapper.properties." >&2
+    exit 1
+  fi
+  if [ $distributionSha256Result = false ]; then
+    echo "Error: Failed to validate Maven distribution SHA-256, your Maven 
distribution might be compromised." >&2
+    echo "If you updated your Maven version, you need to update the specified 
distributionSha256Sum property." >&2
+    exit 1
+  fi
+fi
+
+# unzip and move
+if command -v unzip >/dev/null; then
+  unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} 
"$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed 
to unzip"
+else
+  tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} 
"$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed 
to untar"
+fi
+
+# Find the actual extracted directory name (handles snapshots where filename 
!= directory name)
+actualDistributionDir=""
+
+# First try the expected directory name (for regular distributions)
+if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
+  if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
+    actualDistributionDir="$distributionUrlNameMain"
+  fi
+fi
+
+# If not found, search for any directory with the Maven executable (for 
snapshots)
+if [ -z "$actualDistributionDir" ]; then
+  # enable globbing to iterate over items
+  set +f
+  for dir in "$TMP_DOWNLOAD_DIR"/*; do
+    if [ -d "$dir" ]; then
+      if [ -f "$dir/bin/$MVN_CMD" ]; then
+        actualDistributionDir="$(basename "$dir")"
+        break
+      fi
+    fi
+  done
+  set -f
+fi
+
+if [ -z "$actualDistributionDir" ]; then
+  verbose "Contents of $TMP_DOWNLOAD_DIR:"
+  verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
+  die "Could not find Maven distribution directory in extracted archive"
+fi
+
+verbose "Found extracted Maven distribution directory: $actualDistributionDir"
+printf %s\\n "$distributionUrl" 
>"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
+mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d 
"$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
+
+clean || :
+exec_maven "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
new file mode 100644
index 00000000000..5761d948924
--- /dev/null
+++ b/mvnw.cmd
@@ -0,0 +1,189 @@
+<# : batch portion
+@REM 
----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM 
----------------------------------------------------------------------------
+
+@REM 
----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.3.4
+@REM
+@REM Optional ENV vars
+@REM   MVNW_REPOURL - repo url base for downloading maven distribution
+@REM   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+@REM   MVNW_VERBOSE - true: enable verbose log; others: silence the output
+@REM 
----------------------------------------------------------------------------
+
+@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
+@SET __MVNW_CMD__=
+@SET __MVNW_ERROR__=
+@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
+@SET PSModulePath=
+@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& 
{$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock 
([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
+  IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE 
(echo %%A=%%B)
+)
+@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
+@SET __MVNW_PSMODULEP_SAVE=
+@SET __MVNW_ARG0_NAME__=
+@SET MVNW_USERNAME=
+@SET MVNW_PASSWORD=
+@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*)
+@echo Cannot start maven from wrapper >&2 && exit /b 1
+@GOTO :EOF
+: end batch / begin powershell #>
+
+$ErrorActionPreference = "Stop"
+if ($env:MVNW_VERBOSE -eq "true") {
+  $VerbosePreference = "Continue"
+}
+
+# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
+$distributionUrl = (Get-Content -Raw 
"$scriptDir/.mvn/wrapper/maven-wrapper.properties" | 
ConvertFrom-StringData).distributionUrl
+if (!$distributionUrl) {
+  Write-Error "cannot read distributionUrl property in 
$scriptDir/.mvn/wrapper/maven-wrapper.properties"
+}
+
+switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
+  "maven-mvnd-*" {
+    $USE_MVND = $true
+    $distributionUrl = $distributionUrl -replace 
'-bin\.[^.]*$',"-windows-amd64.zip"
+    $MVN_CMD = "mvnd.cmd"
+    break
+  }
+  default {
+    $USE_MVND = $false
+    $MVN_CMD = $script -replace '^mvnw','mvn'
+    break
+  }
+}
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: 
~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
+if ($env:MVNW_REPOURL) {
+  $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else 
{ "/maven/mvnd/" }
+  $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl 
-replace "^.*$MVNW_REPO_PATTERN",'')"
+}
+$distributionUrlName = $distributionUrl -replace '^.*/',''
+$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' 
-replace '-bin$',''
+
+$MAVEN_M2_PATH = "$HOME/.m2"
+if ($env:MAVEN_USER_HOME) {
+  $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
+}
+
+if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
+    New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
+}
+
+$MAVEN_WRAPPER_DISTS = $null
+if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
+  $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
+} else {
+  $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
+}
+
+$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
+$MAVEN_HOME_NAME = 
([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl)
 | ForEach-Object {$_.ToString("x2")}) -join ''
+$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
+
+if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
+  Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+  Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
+  exit $?
+}
+
+if (! $distributionUrlNameMain -or ($distributionUrlName -eq 
$distributionUrlNameMain)) {
+  Write-Error "distributionUrl is not valid, must end with *-bin.zip, but 
found $distributionUrl"
+}
+
+# prepare tmp dir
+$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
+$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path 
"$TMP_DOWNLOAD_DIR_HOLDER.dir"
+$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
+trap {
+  if ($TMP_DOWNLOAD_DIR.Exists) {
+    try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+    catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+  }
+}
+
+New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
+
+# Download and Install Apache Maven
+Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+Write-Verbose "Downloading from: $distributionUrl"
+Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+$webclient = New-Object System.Net.WebClient
+if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
+  $webclient.Credentials = New-Object 
System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
+}
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+$webclient.DownloadFile($distributionUrl, 
"$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+$distributionSha256Sum = (Get-Content -Raw 
"$scriptDir/.mvn/wrapper/maven-wrapper.properties" | 
ConvertFrom-StringData).distributionSha256Sum
+if ($distributionSha256Sum) {
+  if ($USE_MVND) {
+    Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease 
disable validation by removing 'distributionSha256Sum' from your 
maven-wrapper.properties."
+  }
+  Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function 
Get-FileHash
+  if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm 
SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
+    Write-Error "Error: Failed to validate Maven distribution SHA-256, your 
Maven distribution might be compromised. If you updated your Maven version, you 
need to update the specified distributionSha256Sum property."
+  }
+}
+
+# unzip and move
+Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath 
"$TMP_DOWNLOAD_DIR" | Out-Null
+
+# Find the actual extracted directory name (handles snapshots where filename 
!= directory name)
+$actualDistributionDir = ""
+
+# First try the expected directory name (for regular distributions)
+$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
+$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
+if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path 
$expectedMvnPath -PathType Leaf)) {
+  $actualDistributionDir = $distributionUrlNameMain
+}
+
+# If not found, search for any directory with the Maven executable (for 
snapshots)
+if (!$actualDistributionDir) {
+  Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
+    $testPath = Join-Path $_.FullName "bin/$MVN_CMD"
+    if (Test-Path -Path $testPath -PathType Leaf) {
+      $actualDistributionDir = $_.Name
+    }
+  }
+}
+
+if (!$actualDistributionDir) {
+  Write-Error "Could not find Maven distribution directory in extracted 
archive"
+}
+
+Write-Verbose "Found extracted Maven distribution directory: 
$actualDistributionDir"
+Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName 
$MAVEN_HOME_NAME | Out-Null
+try {
+  Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination 
$MAVEN_HOME_PARENT | Out-Null
+} catch {
+  if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
+    Write-Error "fail to move MAVEN_HOME"
+  }
+} finally {
+  try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+  catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+}
+
+Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to