You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ratis.apache.org by iv...@apache.org on 2026/10/23 01:17:20 UTC
(ratis) branch master updated: RATIS-2772. Add ErrorProne into Ratis verification pipeline (#1658)
This is an automated email from the ASF dual-hosted git repository.
ivandika3 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ratis.git
The following commit(s) were added to refs/heads/master by this push:
new f549f144e RATIS-2772. Add ErrorProne into Ratis verification pipeline (#1658)
f549f144e is described below
commit f549f144ef383e80ed21930a2468dcc1bb21c718
Author: Ivan Andika <iv...@apache.org>
AuthorDate: Fri Oct 23 09:17:14 2026 +0800
RATIS-2772. Add ErrorProne into Ratis verification pipeline (#1658)
---
.github/dependabot.yml | 3 ++
.github/workflows/ci.yaml | 9 ++++
BUILDING.md | 22 ++++++++++
dev-support/checks/errorprone.sh | 57 ++++++++++++++++++++++++
dev-support/tests/test-errorprone.sh | 85 ++++++++++++++++++++++++++++++++++++
pom.xml | 44 +++++++++++++++++++
6 files changed, 220 insertions(+)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index e33f4fcc2..1e49f962d 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -42,6 +42,9 @@ updates:
versions: [">=4.9.0.0"]
- dependency-name: "org.mockito:mockito-core"
versions: [">=5.0.0"]
+ # Error Prone runs on Java 17 in CI
+ - dependency-name: "com.google.errorprone:error_prone_core"
+ versions: [">=2.43.0"]
# requires Java 17
- dependency-name: "org.apache.hadoop:*"
versions: [">=3.5.0"]
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 49e0caeb3..b523fc8d6 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -97,6 +97,15 @@ jobs:
secrets:
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
+ errorprone:
+ uses: $/.github/workflows/check.yaml
+ with:
+ java-version: '17'
+ script: errorprone
+ timeout-minutes: 30
+ secrets:
+ DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
+
unit:
strategy:
matrix:
diff --git a/BUILDING.md b/BUILDING.md
index 68b4c0b88..930a5223a 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -30,6 +30,28 @@ $ mvn clean package -DskipTests
Note: subsequent builds could be faster with skiping shading/protobuf compile steps.
See the next section for more info.
+## Error Prone
+
+Run [Error Prone](https://errorprone.info/) static analysis with JDK 17 or 21:
+
+```
+$ dev-support/checks/errorprone.sh
+```
+
+The check compiles main and test sources without running tests. Reports are written to
+`target/errorprone`: `output.log` contains the complete build output, `diagnostics.txt`
+contains compiler diagnostics, and `summary.txt` contains errors. Warnings do not fail the check.
+Generated sources are excluded from Error Prone analysis.
+
+The Maven profile can also be used directly:
+
+```
+$ mvn clean test-compile -Perrorprone -DskipTests
+```
+
+Normal builds do not enable Error Prone and continue to support Java 8.
+To test the check script's report handling, run `bash dev-support/tests/test-errorprone.sh`.
+
# Thirdparty
All bundled thirdparty dependencies are centralized in the *ratis-thirdparty* module
diff --git a/dev-support/checks/errorprone.sh b/dev-support/checks/errorprone.sh
new file mode 100755
index 000000000..4ca4a9e59
--- /dev/null
+++ b/dev-support/checks/errorprone.sh
@@ -0,0 +1,57 @@
+#!/usr/bin/env bash
+# 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.
+
+set -u -o pipefail
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+cd "$DIR/../.." || exit 1
+
+source "${DIR}/../find_maven.sh"
+
+REPORT_DIR=${OUTPUT_DIR:-"$DIR/../../target/errorprone"}
+OUTPUT_LOG=$(mktemp)
+trap 'rm -f "$OUTPUT_LOG"' EXIT
+
+MAVEN_OPTIONS='-B -fae -Perrorprone -DskipTests -Djacoco.skip'
+# Cached compilation does not emit compiler diagnostics.
+MAVEN_OPTIONS="$MAVEN_OPTIONS -Ddevelocity.cache.local.enabled=false"
+# Timestamp prefixes would prevent matching diagnostics.
+MAVEN_OPTIONS="$MAVEN_OPTIONS -Dorg.slf4j.simpleLogger.showDateTime=false"
+
+#shellcheck disable=SC2086
+${MVN} ${MAVEN_OPTIONS} clean test-compile "$@" 2>&1 | tee "$OUTPUT_LOG"
+rc=$?
+
+# Create reports after clean, which removes the default report directory.
+mkdir -p "$REPORT_DIR"
+mv "$OUTPUT_LOG" "${REPORT_DIR}/output.log"
+trap - EXIT
+
+MAVEN_DIAGNOSTIC_PATTERN='^\[(ERROR|WARNING)\] .*:\[[0-9]+,[0-9]+\] \[[^]]+\]'
+JAVAC_DIAGNOSTIC_PATTERN='^.*:[0-9]+: (error|warning): \[[^]]+\]'
+grep -E "${MAVEN_DIAGNOSTIC_PATTERN}|${JAVAC_DIAGNOSTIC_PATTERN}" "${REPORT_DIR}/output.log" \
+ | awk '!seen[$0]++' > "${REPORT_DIR}/diagnostics.txt"
+
+grep -E '^\[ERROR\]|:[0-9]+: error:' "${REPORT_DIR}/diagnostics.txt" > "${REPORT_DIR}/summary.txt" || true
+if [[ ${rc} -ne 0 && ! -s "${REPORT_DIR}/summary.txt" ]]; then
+ echo 'Unknown failure, check output.log' > "${REPORT_DIR}/summary.txt"
+fi
+wc -l < "${REPORT_DIR}/summary.txt" | tr -d ' ' > "${REPORT_DIR}/failures"
+
+if [[ -s "${REPORT_DIR}/summary.txt" ]]; then
+ exit 1
+fi
+exit ${rc}
diff --git a/dev-support/tests/test-errorprone.sh b/dev-support/tests/test-errorprone.sh
new file mode 100755
index 000000000..f407a6e4a
--- /dev/null
+++ b/dev-support/tests/test-errorprone.sh
@@ -0,0 +1,85 @@
+#!/usr/bin/env bash
+# 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.
+
+set -eu
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+TEST_DIR=$(mktemp -d)
+trap 'rm -rf "$TEST_DIR"' EXIT
+export TEST_DIR
+export OUTPUT_DIR="${TEST_DIR}/report"
+export MAVEN="${TEST_DIR}/mvn"
+
+cat > "$MAVEN" <<'EOF'
+#!/usr/bin/env bash
+printf '%s\n' "$@" > "${TEST_DIR}/args"
+# A clean build removes reports created before Maven runs.
+rm -rf "$OUTPUT_DIR"
+cat "${TEST_DIR}/stdout"
+cat "${TEST_DIR}/stderr" >&2
+exit "${MAVEN_EXIT_CODE}"
+EOF
+chmod +x "$MAVEN"
+
+run_check() {
+ local expected=$1
+ local actual=0
+ bash "${DIR}/../checks/errorprone.sh" -Dtest.option=true > "${TEST_DIR}/output" 2>&1 || actual=$?
+ if [[ "$actual" -ne "$expected" ]]; then
+ cat "${TEST_DIR}/output"
+ echo "Expected exit $expected, got $actual" >&2
+ exit 1
+ fi
+}
+
+export MAVEN_EXIT_CODE=1
+cat > "${TEST_DIR}/stdout" <<'EOF'
+[WARNING] /src/Legacy.java:[1,1] [JdkObsolete] warning finding
+[ERROR] /src/Format.java:[2,1] [FormatString] error finding
+[ERROR] /src/Format.java:[2,1] [FormatString] error finding
+[ERROR] Failed to execute goal compiler:compile
+EOF
+cat > "${TEST_DIR}/stderr" <<'EOF'
+/src/Raw.java:3: warning: [Custom-Rule_1] raw warning
+/src/Raw.java:4: error: [RawError] raw error
+EOF
+run_check 1
+[[ $(wc -l < "$OUTPUT_DIR/diagnostics.txt") -eq 4 ]]
+[[ $(wc -l < "$OUTPUT_DIR/summary.txt") -eq 2 ]]
+[[ $(cat "$OUTPUT_DIR/failures") -eq 2 ]]
+grep -q 'JdkObsolete' "$OUTPUT_DIR/diagnostics.txt"
+grep -q 'RawError' "$OUTPUT_DIR/summary.txt"
+! grep -q 'warning\|WARNING\|Failed to execute' "$OUTPUT_DIR/summary.txt"
+for arg in -Perrorprone -DskipTests clean test-compile -Dtest.option=true; do
+ grep -qx -- "$arg" "${TEST_DIR}/args"
+done
+
+export MAVEN_EXIT_CODE=0
+printf '%s\n' '[WARNING] /src/Legacy.java:[1,1] [JdkObsolete] warning finding' > "${TEST_DIR}/stdout"
+: > "${TEST_DIR}/stderr"
+run_check 0
+[[ $(wc -l < "$OUTPUT_DIR/diagnostics.txt") -eq 1 ]]
+[[ ! -s "$OUTPUT_DIR/summary.txt" ]]
+[[ $(cat "$OUTPUT_DIR/failures") -eq 0 ]]
+
+export MAVEN_EXIT_CODE=1
+printf '%s\n' '[ERROR] Dependency resolution failed' > "${TEST_DIR}/stdout"
+run_check 1
+[[ ! -s "$OUTPUT_DIR/diagnostics.txt" ]]
+grep -qx 'Unknown failure, check output.log' "$OUTPUT_DIR/summary.txt"
+[[ $(cat "$OUTPUT_DIR/failures") -eq 1 ]]
+
+echo 'Error Prone check tests passed'
diff --git a/pom.xml b/pom.xml
index 6b02d878a..1235a70cc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -164,6 +164,8 @@
<protobuf-maven-plugin.version>0.6.1</protobuf-maven-plugin.version>
<cyclonedx.version>2.9.3</cyclonedx.version>
+ <errorprone.version>2.42.0</errorprone.version>
+
<spotbugs.version>4.8.6</spotbugs.version>
<spotbugs-plugin.version>4.8.6.8</spotbugs-plugin.version>
@@ -785,6 +787,48 @@
</build>
<profiles>
+ <profile>
+ <id>errorprone</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <fork>true</fork>
+ <annotationProcessorPaths combine.children="append">
+ <path>
+ <groupId>com.google.errorprone</groupId>
+ <artifactId>error_prone_core</artifactId>
+ <version>${errorprone.version}</version>
+ </path>
+ </annotationProcessorPaths>
+ <compilerArgs combine.children="append">
+ <arg>-XDaddTypeAnnotationsToSymbol=true</arg>
+ <arg>-XDcompilePolicy=simple</arg>
+ <arg>--should-stop=ifError=FLOW</arg>
+ <arg>-Xplugin:ErrorProne -XepDisableWarningsInGeneratedCode -XepExcludedPaths:.*/target/generated(-test)?-sources/.*</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
+ <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
+ <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
+ <!-- Forces the compiler process to output in English -->
+ <arg>-J-Duser.language=en</arg>
+ <arg>-J-Duser.country=US</arg>
+ </compilerArgs>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
<profile>
<id>experiments-build</id>
<activation>