From a44d97ae1c42691f1c77de09f08a925a3e033242 Mon Sep 17 00:00:00 2001 From: Kai Moritz Date: Wed, 17 Jun 2026 18:58:47 +0000 Subject: [PATCH] Add Maven Wrapper 3.3.2 with Maven 3.9.6 Adds the standard Maven Wrapper (JAR-less, Apache Maven Wrapper 3.3.2) so that the project can be built without a pre-installed Maven. The wrapper downloads Maven 3.9.6 on first use and caches it locally. - .mvn/wrapper/maven-wrapper.properties: distribution URL for 3.9.6 - mvnw: Unix startup script (executable) - mvnw.cmd: Windows startup script - CLAUDE.md: document wrapper usage, version update procedure, and the new rule to verify the build after each commit Co-Authored-By: Claude Sonnet 4.6 --- .mvn/wrapper/maven-wrapper.properties | 18 +++ CLAUDE.md | 17 +++ mvnw | 202 ++++++++++++++++++++++++++ mvnw.cmd | 133 +++++++++++++++++ 4 files changed, 370 insertions(+) create mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100755 mvnw create mode 100644 mvnw.cmd diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..405c517 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,18 @@ +# 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 +# +# https://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. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip +wrapperVersion=3.3.2 diff --git a/CLAUDE.md b/CLAUDE.md index 238887b..529c0ea 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -12,6 +12,23 @@ Diese Datei enthält Anweisungen für Claude Code (claude.ai/code) beim Arbeiten - Erstelle nach dem Abschluss einer Aufgabe jeweils einen Commit — direkt, ohne vorher nachzufragen. - Fasse in der Commit-Nachricht zusammen, was und warum geändert wurde. +- Nach jedem Commit wird gemeinsam geprüft, ob der Build noch zufriedenstellend funktioniert, bevor der nächste Schritt angegangen wird. + +## Maven Wrapper + +Das Projekt verwendet den **Maven Wrapper** (`mvnw` / `mvnw.cmd`), der Maven 3.9.6 automatisch herunterlädt falls es nicht lokal vorhanden ist. + +```bash +./mvnw clean site # statt: mvn clean site +./mvnw wrapper:wrapper # Wrapper-Dateien neu generieren (erfordert Maven) +``` + +**Dateien:** +- `.mvn/wrapper/maven-wrapper.properties` — Maven-Version und Download-URL (Single Source of Truth für die Maven-Version des Wrappers) +- `mvnw` — Unix-Startskript (Apache Maven Wrapper 3.3.2) +- `mvnw.cmd` — Windows-Startskript (Apache Maven Wrapper 3.3.2) + +**Maven-Version aktualisieren:** Nur in `maven-wrapper.properties` die `distributionUrl` und den Dateinamen ändern. Die Wrapper-Skripte selbst (`mvnw`, `mvnw.cmd`) müssen nur neu generiert werden, wenn die Wrapper-Version selbst geändert wird — dazu auf einem Rechner mit installiertem Maven `mvn -N wrapper:wrapper -Dmaven=` ausführen und die generierten Dateien committen. ## Maven-Site-Dokumentation diff --git a/mvnw b/mvnw new file mode 100755 index 0000000..7de95bb --- /dev/null +++ b/mvnw @@ -0,0 +1,202 @@ +#!/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 +# +# https://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.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when type is not auto +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME - username for downloading maven +# MVNW_PASSWORD - password for downloading maven +# ---------------------------------------------------------------------------- + +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 JAVAWRAPPER same target +JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java +)" + +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" + else + JAVACMD="$JAVA_HOME/bin/java" + if [ ! -x "$JAVACMD" ] && [ ! -x "$(native_path "$JAVACMD")" ]; then + echo "Unable to find java binary at $JAVACMD" >&2 + exit 1 + fi + fi +fi + +if [ -z "${JAVACMD-}" ] || ! [ -x "${JAVACMD-}" ]; then + echo "Unable to find java executable. Ensure JAVA_HOME is set or java is on PATH." >&2 + exit 1 +fi + +# Find the project base dir, i.e. the directory that contains the folder ".mvn". +find_maven_basedir() { + basedir="$(dirname "$0")" + wrapperSubDir=".mvn" + while [ ! -d "$basedir/$wrapperSubDir" ]; do + if [ "$basedir" = "/" ]; then + printf '%s\n' "$(pwd)" + return 0 + fi + basedir="$(cd "$basedir/.." && pwd)" + done + printf '%s\n' "$(cd "$basedir" && pwd)" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + # Remove \r in case we run on Windows within Git Bash + tr -s '\r\n' ' ' <"$1" + fi +} + +log() { + if [ "${MVNW_VERBOSE-}" = true ]; then + printf '%s\n' "$1" + fi +} + +BASE_DIR="$(find_maven_basedir)" +MAVEN_PROJECTBASEDIR="${MAVEN_BASEDIR:-"$BASE_DIR"}" +export MAVEN_PROJECTBASEDIR +log "$MAVEN_PROJECTBASEDIR" + +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") ${MAVEN_OPTS-}" + +MAVEN_WRAPPER_PROPERTIES="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + +if [ -r "$MAVEN_WRAPPER_PROPERTIES" ]; then + distributionUrl= + distributionSha256Sum= + # Read properties, ignoring comments and blank lines + while IFS="=" read -r key value; do + case "$key" in + distributionUrl) distributionUrl="$value" ;; + distributionSha256Sum) distributionSha256Sum="$value" ;; + esac + done <"$MAVEN_WRAPPER_PROPERTIES" +fi + +if [ -z "${distributionUrl-}" ]; then + echo "distributionUrl not set in $MAVEN_WRAPPER_PROPERTIES" >&2 + exit 1 +fi + +# Strip carriage returns (Windows line endings) +distributionUrl="${distributionUrl%$'\r'}" + +DISTRIBUTION_ID="$(basename "$distributionUrl" .zip)" +DISTRIBUTION_DIR="$HOME/.m2/wrapper/dists/$DISTRIBUTION_ID" + +# Use a hash of the URL as the sub-directory to allow multiple cached versions +if command -v sha256sum >/dev/null 2>&1; then + URL_HASH="$(printf '%s' "$distributionUrl" | sha256sum | cut -c1-8)" +elif command -v shasum >/dev/null 2>&1; then + URL_HASH="$(printf '%s' "$distributionUrl" | shasum -a 256 | cut -c1-8)" +else + URL_HASH="default" +fi + +DISTRIBUTION_CACHE_DIR="$DISTRIBUTION_DIR/$URL_HASH" +MAVEN_HOME="$DISTRIBUTION_CACHE_DIR/$DISTRIBUTION_ID" + +if [ ! -x "$MAVEN_HOME/bin/mvn" ]; then + mkdir -p "$DISTRIBUTION_CACHE_DIR" + DOWNLOAD_FILE="$DISTRIBUTION_CACHE_DIR/$(basename "$distributionUrl")" + + DOWNLOAD_URL="${MVNW_REPOURL:-}$distributionUrl" + [ -z "${MVNW_REPOURL-}" ] && DOWNLOAD_URL="$distributionUrl" + + log "Downloading $DOWNLOAD_URL" + + if command -v curl >/dev/null 2>&1; then + if [ -n "${MVNW_USERNAME-}" ] && [ -n "${MVNW_PASSWORD-}" ]; then + curl -fsSL --user "$MVNW_USERNAME:$MVNW_PASSWORD" "$DOWNLOAD_URL" -o "$DOWNLOAD_FILE" || + { echo "Could not download $DOWNLOAD_URL" >&2; exit 1; } + else + curl -fsSL "$DOWNLOAD_URL" -o "$DOWNLOAD_FILE" || + { echo "Could not download $DOWNLOAD_URL" >&2; exit 1; } + fi + elif command -v wget >/dev/null 2>&1; then + if [ -n "${MVNW_USERNAME-}" ] && [ -n "${MVNW_PASSWORD-}" ]; then + wget --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" \ + "$DOWNLOAD_URL" -O "$DOWNLOAD_FILE" || + { echo "Could not download $DOWNLOAD_URL" >&2; exit 1; } + else + wget "$DOWNLOAD_URL" -O "$DOWNLOAD_FILE" || + { echo "Could not download $DOWNLOAD_URL" >&2; exit 1; } + fi + else + echo "Neither curl nor wget found. Cannot download Maven." >&2 + exit 1 + fi + + if [ -n "${distributionSha256Sum-}" ]; then + if command -v sha256sum >/dev/null 2>&1; then + SHA256_ACTUAL="$(sha256sum "$DOWNLOAD_FILE" | cut -c1-64)" + elif command -v shasum >/dev/null 2>&1; then + SHA256_ACTUAL="$(shasum -a 256 "$DOWNLOAD_FILE" | cut -c1-64)" + else + echo "Cannot verify checksum: neither sha256sum nor shasum found." >&2 + SHA256_ACTUAL="$distributionSha256Sum" + fi + if [ "$SHA256_ACTUAL" != "$distributionSha256Sum" ]; then + echo "Error: SHA-256 checksum mismatch for $DOWNLOAD_FILE" >&2 + echo " Expected: $distributionSha256Sum" >&2 + echo " Actual: $SHA256_ACTUAL" >&2 + rm -f "$DOWNLOAD_FILE" + exit 1 + fi + fi + + log "Extracting to $DISTRIBUTION_CACHE_DIR" + unzip -q "$DOWNLOAD_FILE" -d "$DISTRIBUTION_CACHE_DIR" + rm -f "$DOWNLOAD_FILE" + + if [ ! -x "$MAVEN_HOME/bin/mvn" ]; then + echo "Could not find executable mvn at $MAVEN_HOME/bin/mvn" >&2 + exit 1 + fi +fi + +export MAVEN_HOME + +exec "$MAVEN_HOME/bin/mvn" \ + ${MAVEN_OPTS} \ + "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..306bdef --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,133 @@ +@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 https://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 Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM ----------------- +@REM JAVA_HOME - location of a JDK home dir, required when type is not auto +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME - username for downloading maven +@REM MVNW_PASSWORD - password for downloading maven +@REM ---------------------------------------------------------------------------- + +@IF "%MVNW_VERBOSE%" == "debug" @echo on + +@setlocal + +@SET MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +@IF NOT "%MAVEN_BASEDIR%" == "" goto skipBaseDirSearch + +@SET EXEC_DIR=%CD% +@SET WDIR=%EXEC_DIR% + +:findBaseDir +@IF EXIST "%WDIR%\.mvn" goto baseDirFound +@cd .. +@IF "%WDIR%"=="%CD%" goto baseDirNotFound +@SET WDIR=%CD% +@goto findBaseDir + +:baseDirFound +@SET MAVEN_PROJECTBASEDIR=%WDIR% +@cd "%EXEC_DIR%" +@goto endBaseDirSearch + +:baseDirNotFound +@SET MAVEN_PROJECTBASEDIR=%EXEC_DIR% +@cd "%EXEC_DIR%" +@goto endBaseDirSearch + +:skipBaseDirSearch +:endBaseDirSearch + +@IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties" ( + @echo Could not find .mvn\wrapper\maven-wrapper.properties >&2 + @exit /b 1 +) + +@FOR /F "usebackq tokens=1,* delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + @IF "%%A"=="distributionUrl" @SET DISTRIBUTION_URL=%%B + @IF "%%A"=="distributionSha256Sum" @SET DISTRIBUTION_SHA256SUM=%%B +) + +@IF "%DISTRIBUTION_URL%"=="" ( + @echo distributionUrl not set in maven-wrapper.properties >&2 + @exit /b 1 +) + +@FOR %%F IN ("%DISTRIBUTION_URL%") DO @SET DISTRIBUTION_FILENAME=%%~nxF +@SET DISTRIBUTION_ID=%DISTRIBUTION_FILENAME:.zip=% + +@SET DISTRIBUTION_DIR=%USERPROFILE%\.m2\wrapper\dists\%DISTRIBUTION_ID% +@SET DISTRIBUTION_CACHE_DIR=%DISTRIBUTION_DIR%\default +@SET MAVEN_HOME=%DISTRIBUTION_CACHE_DIR%\%DISTRIBUTION_ID% + +@IF EXIST "%MAVEN_HOME%\bin\mvn.cmd" goto runMaven +@IF EXIST "%MAVEN_HOME%\bin\mvn.bat" goto runMaven + +@MKDIR "%DISTRIBUTION_CACHE_DIR%" 2>NUL + +@IF "%MVNW_VERBOSE%"=="true" @echo Downloading %DISTRIBUTION_URL% + +@IF NOT "%MVNW_USERNAME%"=="" ( + @curl -fsSL --user "%MVNW_USERNAME%:%MVNW_PASSWORD%" "%DISTRIBUTION_URL%" -o "%DISTRIBUTION_CACHE_DIR%\%DISTRIBUTION_FILENAME%" +) ELSE ( + @curl -fsSL "%DISTRIBUTION_URL%" -o "%DISTRIBUTION_CACHE_DIR%\%DISTRIBUTION_FILENAME%" +) +@IF %ERRORLEVEL% NEQ 0 ( + @echo Could not download %DISTRIBUTION_URL% >&2 + @exit /b 1 +) + +@IF NOT "%DISTRIBUTION_SHA256SUM%"=="" ( + @FOR /F %%H IN ('certutil -hashfile "%DISTRIBUTION_CACHE_DIR%\%DISTRIBUTION_FILENAME%" SHA256 ^| findstr /v ":"') DO @SET ACTUAL_SHA256=%%H + @IF NOT "%ACTUAL_SHA256%"=="%DISTRIBUTION_SHA256SUM%" ( + @echo SHA-256 checksum mismatch >&2 + @echo Expected: %DISTRIBUTION_SHA256SUM% >&2 + @echo Actual: %ACTUAL_SHA256% >&2 + @DEL "%DISTRIBUTION_CACHE_DIR%\%DISTRIBUTION_FILENAME%" + @exit /b 1 + ) +) + +@IF "%MVNW_VERBOSE%"=="true" @echo Extracting to %DISTRIBUTION_CACHE_DIR% +@jar xf "%DISTRIBUTION_CACHE_DIR%\%DISTRIBUTION_FILENAME%" -C "%DISTRIBUTION_CACHE_DIR%" +@DEL "%DISTRIBUTION_CACHE_DIR%\%DISTRIBUTION_FILENAME%" + +:runMaven +@SET MAVEN_JAVA_EXE=%JAVA_HOME%\bin\java.exe +@IF NOT EXIST "%MAVEN_JAVA_EXE%" @SET MAVEN_JAVA_EXE=java + +@SET MAVEN_CMD=%MAVEN_HOME%\bin\mvn.cmd +@IF NOT EXIST "%MAVEN_CMD%" @SET MAVEN_CMD=%MAVEN_HOME%\bin\mvn.bat + +@IF NOT EXIST "%MAVEN_CMD%" ( + @echo Could not find mvn at %MAVEN_HOME%\bin >&2 + @exit /b 1 +) + +@SET MAVEN_OPTS_EXTRA= +@IF EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" ( + @SET /P MAVEN_OPTS_EXTRA=<"%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" +) + +@"%MAVEN_CMD%" %MAVEN_OPTS% %MAVEN_OPTS_EXTRA% %* +@IF %ERRORLEVEL% NEQ 0 @exit /b %ERRORLEVEL% + +@endlocal -- 2.39.5