From 0c403ab8b507a32da0ea18176e7c1c5ad61f41df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Mej=C3=ADa?= Date: Tue, 5 May 2026 10:55:02 +0200 Subject: [PATCH 1/9] AVRO-4261: [Java] Raise Java minimum to 17 and add Java 25 support Drop Java 8 and 11 support across the build: - Set maven.compiler.source/release to 17 in root and all modules - Update toolchain checks to require JDK 17, 21, and 25 - Update enforcer bytecodeVersion maxJdkVersion to 17 - Replace integration test profiles [11,17,21] with [17,21,25] - Update all CI workflows from JDK [8,11,17,21] to [17,21,25] - Update Dockerfile to install JDK 17, 21, 25 (default 25) - Update Getting Started docs compiler example to Java 17 - Remove dead @EnabledForJreRange(max=JAVA_11) test code --- .github/workflows/codeql-java-analysis.yml | 5 ++-- .github/workflows/deploy-docs.yml | 2 +- .github/workflows/java-publish-snapshot.yml | 5 ++-- .github/workflows/maven4.yml | 5 ++-- .github/workflows/rat.yml | 5 ++-- .github/workflows/spotless.yml | 5 ++-- .github/workflows/test-lang-c.yml | 10 +++---- .github/workflows/test-lang-csharp.yml | 5 ++-- .github/workflows/test-lang-java.yml | 12 ++++---- .github/workflows/test-lang-perl.yml | 5 ++-- .github/workflows/test-lang-php.yml | 5 ++-- .github/workflows/test-lang-py.yml | 5 ++-- .github/workflows/test-lang-ruby.yml | 5 ++-- .../Getting started (Java)/_index.md | 4 +-- doc/examples/java-example/pom.xml | 4 +-- doc/examples/mr-example/pom.xml | 4 +-- lang/java/avro/pom.xml | 24 +++++++-------- lang/java/avro/src/it/pom.xml | 2 +- .../org/apache/avro/reflect/TestReflect.java | 25 ++-------------- lang/java/interop-data-test/pom.xml | 24 +++++++-------- .../interop-data-test/src/it/check/pom.xml | 2 +- .../interop-data-test/src/it/generate/pom.xml | 2 +- lang/java/mapred/pom.xml | 4 +-- lang/java/thrift/pom.xml | 2 +- pom.xml | 29 ++++++++++++------- share/docker/Dockerfile | 6 ++-- 26 files changed, 91 insertions(+), 115 deletions(-) diff --git a/.github/workflows/codeql-java-analysis.yml b/.github/workflows/codeql-java-analysis.yml index b7668b497fd..c532576696b 100644 --- a/.github/workflows/codeql-java-analysis.yml +++ b/.github/workflows/codeql-java-analysis.yml @@ -70,15 +70,14 @@ jobs: # queries: ./path/to/local/query, your-org/your-repo/queries@main queries: +security-and-quality - - name: 'Setup Temurin JDK 8, 11, 17 & 21' + - name: 'Setup Temurin JDK 17, 21 & 25' uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: | - 8 - 11 17 21 + 25 - name: 'Setup Maven 3.9.11' uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index f456026f505..a13067a1432 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -155,9 +155,9 @@ jobs: with: distribution: 'temurin' java-version: | - 11 17 21 + 25 - name: Build Java docs run: | diff --git a/.github/workflows/java-publish-snapshot.yml b/.github/workflows/java-publish-snapshot.yml index c20d218e19e..d2bdbb5d9be 100644 --- a/.github/workflows/java-publish-snapshot.yml +++ b/.github/workflows/java-publish-snapshot.yml @@ -43,15 +43,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: 'Setup Temurin JDK 8, 11, 17 & 21' + - name: 'Setup Temurin JDK 17, 21 & 25' uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: | - 8 - 11 17 21 + 25 - name: 'Setup Maven' uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 diff --git a/.github/workflows/maven4.yml b/.github/workflows/maven4.yml index f19c6dcd355..7adbaeb20f8 100644 --- a/.github/workflows/maven4.yml +++ b/.github/workflows/maven4.yml @@ -50,15 +50,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven-build-cache - - name: 'Setup Temurin JDK 8, 11, 17 & 21' + - name: 'Setup Temurin JDK 17, 21 & 25' uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: | - 8 - 11 17 21 + 25 - name: Setup Maven 4 uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 diff --git a/.github/workflows/rat.yml b/.github/workflows/rat.yml index 96a9c0ec915..763d5f0ddc8 100644 --- a/.github/workflows/rat.yml +++ b/.github/workflows/rat.yml @@ -39,15 +39,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: 'Setup Temurin JDK 8, 11, 17 & 21' + - name: 'Setup Temurin JDK 17, 21 & 25' uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: | - 8 - 11 17 21 + 25 - name: 'Setup Maven 3.9.11' uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 diff --git a/.github/workflows/spotless.yml b/.github/workflows/spotless.yml index 2b4f8bdedf8..410652f5486 100644 --- a/.github/workflows/spotless.yml +++ b/.github/workflows/spotless.yml @@ -42,15 +42,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: 'Setup Temurin JDK 8, 11, 17 & 21' + - name: 'Setup Temurin JDK 17, 21 & 25' uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: | - 8 - 11 17 21 + 25 - name: 'Setup Maven 3.9.11' uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 diff --git a/.github/workflows/test-lang-c.yml b/.github/workflows/test-lang-c.yml index e3afece7c55..fb7e3531d6f 100644 --- a/.github/workflows/test-lang-c.yml +++ b/.github/workflows/test-lang-c.yml @@ -68,15 +68,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: 'Setup Temurin JDK 8, 11, 17 & 21' + - name: 'Setup Temurin JDK 17, 21 & 25' uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: | - 8 - 11 17 21 + 25 - name: 'Setup Maven 3.9.11' uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 @@ -128,15 +127,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: 'Setup Temurin JDK 8, 11, 17 & 21' + - name: 'Setup Temurin JDK 17, 21 & 25' uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: | - 8 - 11 17 21 + 25 - name: 'Setup Maven 3.9.11' uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 diff --git a/.github/workflows/test-lang-csharp.yml b/.github/workflows/test-lang-csharp.yml index af5ddbc8e0c..1c2223115be 100644 --- a/.github/workflows/test-lang-csharp.yml +++ b/.github/workflows/test-lang-csharp.yml @@ -98,15 +98,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: 'Setup Temurin JDK 8, 11, 17 & 21' + - name: 'Setup Temurin JDK 17, 21 & 25' uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: | - 8 - 11 17 21 + 25 - name: 'Setup Maven 3.9.11' uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 diff --git a/.github/workflows/test-lang-java.yml b/.github/workflows/test-lang-java.yml index 97d5111692f..ffdce7ef044 100644 --- a/.github/workflows/test-lang-java.yml +++ b/.github/workflows/test-lang-java.yml @@ -54,14 +54,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: "Setup Temurin JDK 11, 17 & 21" + - name: "Setup Temurin JDK 17, 21 & 25" uses: actions/setup-java@v5 with: distribution: "temurin" java-version: | - 11 17 21 + 25 - name: "Setup Maven 3.9.11" uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 @@ -106,14 +106,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: "Setup Temurin JDK 11, 17 & 21" + - name: "Setup Temurin JDK 17, 21 & 25" uses: actions/setup-java@v5 with: distribution: "temurin" java-version: | - 11 17 21 + 25 - name: "Setup Maven 3.9.11" uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 @@ -164,10 +164,10 @@ jobs: working-directory: . run: mvn -B install -PskipQuality - - name: "Generate Interop Data using Java 11, 17 & 21" + - name: "Generate Interop Data using Java 17, 21 & 25" working-directory: lang/java/interop-data-test run: mvn -B verify -Pgenerate-test-data - - name: "Run Interop Tests using Java 11, 17 & 21" + - name: "Run Interop Tests using Java 17, 21 & 25" working-directory: lang/java/interop-data-test run: mvn -B verify -Pcheck-test-data diff --git a/.github/workflows/test-lang-perl.yml b/.github/workflows/test-lang-perl.yml index b92a13f1855..76bd16cd236 100644 --- a/.github/workflows/test-lang-perl.yml +++ b/.github/workflows/test-lang-perl.yml @@ -113,15 +113,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: 'Setup Temurin JDK 8, 11, 17 & 21' + - name: 'Setup Temurin JDK 17, 21 & 25' uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: | - 8 - 11 17 21 + 25 - name: 'Setup Maven 3.9.11' uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 diff --git a/.github/workflows/test-lang-php.yml b/.github/workflows/test-lang-php.yml index 4359f609dd6..32133d40484 100644 --- a/.github/workflows/test-lang-php.yml +++ b/.github/workflows/test-lang-php.yml @@ -109,15 +109,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: 'Setup Temurin JDK 8, 11, 17 & 21' + - name: 'Setup Temurin JDK 17, 21 & 25' uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: | - 8 - 11 17 21 + 25 - name: 'Setup Maven 3.9.11' uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 diff --git a/.github/workflows/test-lang-py.yml b/.github/workflows/test-lang-py.yml index 1db39c4e069..6c11b505b31 100644 --- a/.github/workflows/test-lang-py.yml +++ b/.github/workflows/test-lang-py.yml @@ -127,15 +127,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: "Setup Temurin JDK 8, 11, 17 & 21" + - name: "Setup Temurin JDK 17, 21 & 25" uses: actions/setup-java@v5 with: distribution: "temurin" java-version: | - 8 - 11 17 21 + 25 - name: "Setup Maven 3.9.11" uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 diff --git a/.github/workflows/test-lang-ruby.yml b/.github/workflows/test-lang-ruby.yml index bf98f9ccb78..fc30937641c 100644 --- a/.github/workflows/test-lang-ruby.yml +++ b/.github/workflows/test-lang-ruby.yml @@ -117,15 +117,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: 'Setup Temurin JDK 8, 11, 17 & 21' + - name: 'Setup Temurin JDK 17, 21 & 25' uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: | - 8 - 11 17 21 + 25 - name: 'Setup Maven 3.9.11' uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5 diff --git a/doc/content/en/docs/++version++/Getting started (Java)/_index.md b/doc/content/en/docs/++version++/Getting started (Java)/_index.md index 44aeae4767d..bf1acc01fc4 100644 --- a/doc/content/en/docs/++version++/Getting started (Java)/_index.md +++ b/doc/content/en/docs/++version++/Getting started (Java)/_index.md @@ -69,8 +69,8 @@ As well as the Avro Maven plugin (for performing code generation): org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 + 17 + 17 ``` diff --git a/doc/examples/java-example/pom.xml b/doc/examples/java-example/pom.xml index 2fb9ba89d36..424d54e7f7f 100644 --- a/doc/examples/java-example/pom.xml +++ b/doc/examples/java-example/pom.xml @@ -49,8 +49,8 @@ maven-compiler-plugin 3.8.1 - 11 - 11 + 17 + 17 diff --git a/doc/examples/mr-example/pom.xml b/doc/examples/mr-example/pom.xml index 089adf79764..71e017e5705 100644 --- a/doc/examples/mr-example/pom.xml +++ b/doc/examples/mr-example/pom.xml @@ -39,8 +39,8 @@ maven-compiler-plugin 3.8.1 - 11 - 11 + 17 + 17 diff --git a/lang/java/avro/pom.xml b/lang/java/avro/pom.xml index 8cab8b75f5c..7df974d1605 100644 --- a/lang/java/avro/pom.xml +++ b/lang/java/avro/pom.xml @@ -154,50 +154,50 @@ - Run all tests under Java 11 + Run all tests under Java 17 run - [11,12) + [17,18) - 11 + 17 - ${project.build.directory}/it-jdk-11 + ${project.build.directory}/it-jdk-17 - Run all tests under Java 17 + Run all tests under Java 21 run - [17,18) + [21,22) - 17 + 21 - ${project.build.directory}/it-jdk-17 + ${project.build.directory}/it-jdk-21 - Run all tests under Java 21 + Run all tests under Java 25 run - [21,22) + [25,26) - 21 + 25 - ${project.build.directory}/it-jdk-21 + ${project.build.directory}/it-jdk-25 diff --git a/lang/java/avro/src/it/pom.xml b/lang/java/avro/src/it/pom.xml index bd9bc523d7a..b7fc1cb2835 100644 --- a/lang/java/avro/src/it/pom.xml +++ b/lang/java/avro/src/it/pom.xml @@ -30,7 +30,7 @@ UTF-8 UTF-8 - 8 + 17 diff --git a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java index cf0e99756eb..d9e1bec4026 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java +++ b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java @@ -55,8 +55,6 @@ import org.apache.avro.util.Utf8; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable; -import org.junit.jupiter.api.condition.EnabledForJreRange; -import org.junit.jupiter.api.condition.JRE; public class TestReflect { @@ -1211,30 +1209,11 @@ public static void checkBinary(Schema schema, Object datum) throws IOException { /** Test that the error message contains the name of the class. */ @Test - @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_11, disabledReason = "Java 11 announced: All illegal access operations will be denied in a future release") - // Java 11: - // - WARNING: An illegal reflective access operation has occurred - // - WARNING: Illegal reflective access by - // org.apache.avro.reflect.FieldAccessReflect$ReflectionBasedAccessor to field - // java.lang.String.coder - // - WARNING: Please consider reporting this to the maintainers of - // org.apache.avro.reflect.FieldAccessReflect$ReflectionBasedAccessor - // - WARNING: Use --illegal-access=warn to enable warnings of further illegal - // reflective access operations - // - WARNING: All illegal access operations will be denied in a future release - // Java 17: - // - [ERROR] org.apache.avro.reflect.TestReflect.reflectFieldError -- Time - // elapsed: 0.015 s <<< ERROR! - // - java.lang.reflect.InaccessibleObjectException: Unable to make field private - // final byte java.lang.String.coder accessible: module java.base does not - // "opens java.lang" to unnamed module @5a6d67c3 void reflectFieldError() throws Exception { Object datum = ""; - try { + assertThrows(java.lang.reflect.InaccessibleObjectException.class, () -> { ReflectData.get().getField(datum, "notAFieldOfString", 0); - } catch (AvroRuntimeException e) { - assertTrue(e.getMessage().contains(datum.getClass().getName())); - } + }); } @AvroAlias(alias = "a", space = "b") diff --git a/lang/java/interop-data-test/pom.xml b/lang/java/interop-data-test/pom.xml index c691665ef2d..9f8cbdd0e72 100644 --- a/lang/java/interop-data-test/pom.xml +++ b/lang/java/interop-data-test/pom.xml @@ -69,50 +69,50 @@ - ${invoker-action} under Java 11 + ${invoker-action} under Java 17 run - [11,12) + [17,18) - 11 + 17 - ${project.build.directory}/it-jdk-11 + ${project.build.directory}/it-jdk-17 - ${invoker-action} under Java 17 + ${invoker-action} under Java 21 run - [17,18) + [21,22) - 17 + 21 - ${project.build.directory}/it-jdk-17 + ${project.build.directory}/it-jdk-21 - ${invoker-action} under Java 21 + ${invoker-action} under Java 25 run - [21,22) + [25,26) - 21 + 25 - ${project.build.directory}/it-jdk-21 + ${project.build.directory}/it-jdk-25 diff --git a/lang/java/interop-data-test/src/it/check/pom.xml b/lang/java/interop-data-test/src/it/check/pom.xml index 64eeaf4c850..6e58790401e 100644 --- a/lang/java/interop-data-test/src/it/check/pom.xml +++ b/lang/java/interop-data-test/src/it/check/pom.xml @@ -30,7 +30,7 @@ UTF-8 UTF-8 - 11 + 17 ../../../../../.. ${main.basedir}/build/interop/data/ diff --git a/lang/java/interop-data-test/src/it/generate/pom.xml b/lang/java/interop-data-test/src/it/generate/pom.xml index c79dd35db0e..d9e83366a8d 100644 --- a/lang/java/interop-data-test/src/it/generate/pom.xml +++ b/lang/java/interop-data-test/src/it/generate/pom.xml @@ -30,7 +30,7 @@ UTF-8 UTF-8 - 11 + 17 ../../../../../.. diff --git a/lang/java/mapred/pom.xml b/lang/java/mapred/pom.xml index 91982cfd110..4b3f5e544ef 100644 --- a/lang/java/mapred/pom.xml +++ b/lang/java/mapred/pom.xml @@ -45,8 +45,8 @@ org.apache.avro.mapred*;version="${project.version}", org.apache.avro.hadoop*;version="${project.version}", - 8 - 8 + 17 + 17 diff --git a/lang/java/thrift/pom.xml b/lang/java/thrift/pom.xml index 2ba57eeb221..cda0ea7117e 100644 --- a/lang/java/thrift/pom.xml +++ b/lang/java/thrift/pom.xml @@ -95,7 +95,7 @@ - 11 + 17 diff --git a/pom.xml b/pom.xml index e17dc884d3b..80977ea9565 100644 --- a/pom.xml +++ b/pom.xml @@ -40,8 +40,8 @@ Java artifacts are copied to the final build destination with a custom profile. --> - 11 - 11 + 17 + 17 ${project.basedir} dist build/avro-doc-${project.version}/api @@ -182,32 +182,41 @@ maven-toolchains-plugin - Ensure ToolChain for JDK 11 is available + Ensure ToolChain for JDK 17 is available select-jdk-toolchain - [11,12) + [17,18) - Ensure ToolChain for JDK 17 is available + Ensure ToolChain for JDK 21 is available select-jdk-toolchain - [17,18) + [21,22) + + + + Ensure ToolChain for JDK 25 is available + + select-jdk-toolchain + + + [25,26) - Build using JDK 21 + Build using JDK 25 select-jdk-toolchain IfSame - [21,22) + [25,26) @@ -225,13 +234,13 @@ - 11 + 17 test provided diff --git a/share/docker/Dockerfile b/share/docker/Dockerfile index 5932e5be7b1..3dfd8bd7c5d 100644 --- a/share/docker/Dockerfile +++ b/share/docker/Dockerfile @@ -59,9 +59,9 @@ RUN apt-get -qqy update \ libsnappy1v5 \ libssl-dev \ make \ - openjdk-11-jdk \ openjdk-17-jdk \ openjdk-21-jdk \ + openjdk-25-jdk \ perl \ source-highlight \ subversion \ @@ -217,7 +217,7 @@ RUN cd /opt ; \ ENV PATH=$PATH:/opt/dotnet -# Since we want the JDK21 as a default, we have to re-prepend it to the PATH. -RUN update-java-alternatives -s "java-1.21.*" +# Since we want the JDK25 as a default, we have to re-prepend it to the PATH. +RUN update-java-alternatives -s "java-1.25.*" CMD ["/bin/bash", "-i"] From 7f8052a32ab12a738934e9eb6d3cd579f375d42a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Mej=C3=ADa?= Date: Tue, 5 May 2026 10:59:34 +0200 Subject: [PATCH 2/9] AVRO-4261: [Java] Remove module-info ignoreClasses workaround from enforcer plugin This hack was needed when maxJdkVersion was 8/11 because module-info classes (Java 9 bytecode) would be incorrectly flagged. With the minimum now at 17, module-info passes validation naturally. --- pom.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pom.xml b/pom.xml index 80977ea9565..cbe5587dd0e 100644 --- a/pom.xml +++ b/pom.xml @@ -239,14 +239,6 @@ test provided - - - module-info - - - 4.0.0 - - - avro-parent - org.apache.avro - 1.13.0-SNAPSHOT - ../ - - - java17-test - Avro Java 17 Tests - Unit tests that require java 17 language support. - https://avro.apache.org/ - - - 17 - 17 - 17 - ${project.parent.parent.basedir} - - - - - ${project.groupId} - avro - ${project.version} - - - - - - - org.apache.maven.plugins - maven-deploy-plugin - - true - - - - org.apache.maven.plugins - maven-compiler-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - - - - \ No newline at end of file diff --git a/lang/java/pom.xml b/lang/java/pom.xml index eece7212f8c..6991689808a 100644 --- a/lang/java/pom.xml +++ b/lang/java/pom.xml @@ -91,7 +91,6 @@ integration-test perf interop-data-test - java17-test From 4d176f8b655fb297b0089a1b098f24817633cb0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Mej=C3=ADa?= Date: Fri, 22 May 2026 14:52:44 +0200 Subject: [PATCH 4/9] AVRO-4261: [Java] Reenable unused imports validation --- .../org/apache/avro/TestBigDecimalConversion.java | 1 - .../src/test/java/org/apache/avro/TestProtocol.java | 13 ------------- .../avro/TestSchemaCompatibilityEnumDefaults.java | 1 - .../TestSchemaCompatibilityMissingUnionBranch.java | 3 --- .../test/java/org/apache/avro/TestUnionError.java | 1 - .../avro/io/TestBlockingDirectBinaryEncoder.java | 2 -- .../test/java/org/apache/avro/io/TestEncoders.java | 2 -- .../java/org/apache/avro/reflect/TestReflect.java | 1 - .../org/apache/avro/reflect/TestReflectData.java | 1 - .../avro/specific/TestRecordWithMapsAndArrays.java | 3 --- .../test/java/org/apache/avro/specific/int$.java | 1 - .../org/apache/avro/specific/TestSpecificData.java | 1 - .../avro/ipc/netty/TestNettyServerWithSSL.java | 1 - .../compiler/specific/TestSpecificCompiler.java | 2 -- .../java/org/apache/avro/mojo/TestInduceMojo.java | 1 - .../java/org/apache/avro/mojo/TestSchemaMojo.java | 1 - lang/java/pom.xml | 3 +-- 17 files changed, 1 insertion(+), 37 deletions(-) diff --git a/lang/java/avro/src/test/java/org/apache/avro/TestBigDecimalConversion.java b/lang/java/avro/src/test/java/org/apache/avro/TestBigDecimalConversion.java index e781fe07bd9..0913b1fd056 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/TestBigDecimalConversion.java +++ b/lang/java/avro/src/test/java/org/apache/avro/TestBigDecimalConversion.java @@ -19,7 +19,6 @@ package org.apache.avro; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; diff --git a/lang/java/avro/src/test/java/org/apache/avro/TestProtocol.java b/lang/java/avro/src/test/java/org/apache/avro/TestProtocol.java index cc59a6cd996..7d543a35dac 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/TestProtocol.java +++ b/lang/java/avro/src/test/java/org/apache/avro/TestProtocol.java @@ -17,24 +17,11 @@ */ package org.apache.avro; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericDatumWriter; -import org.apache.avro.generic.IndexedRecord; -import org.apache.avro.io.EncoderFactory; -import org.apache.avro.io.JsonEncoder; - -import com.fasterxml.jackson.databind.JsonNode; - -import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static org.junit.jupiter.api.Assertions.*; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.util.Collections; import org.junit.jupiter.api.Test; diff --git a/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibilityEnumDefaults.java b/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibilityEnumDefaults.java index 44d468c7dea..0f050b59c47 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibilityEnumDefaults.java +++ b/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibilityEnumDefaults.java @@ -27,7 +27,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.ByteArrayOutputStream; -import java.util.concurrent.Callable; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericDatumReader; diff --git a/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibilityMissingUnionBranch.java b/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibilityMissingUnionBranch.java index 3e84a5337c9..6b4bc26624f 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibilityMissingUnionBranch.java +++ b/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibilityMissingUnionBranch.java @@ -22,9 +22,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; import java.util.Collections; import java.util.List; diff --git a/lang/java/avro/src/test/java/org/apache/avro/TestUnionError.java b/lang/java/avro/src/test/java/org/apache/avro/TestUnionError.java index d5847ba36a9..dbdc4bcb78e 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/TestUnionError.java +++ b/lang/java/avro/src/test/java/org/apache/avro/TestUnionError.java @@ -23,7 +23,6 @@ import org.apache.avro.generic.GenericRecord; import org.apache.avro.io.BinaryDecoder; import org.apache.avro.io.BinaryEncoder; -import org.apache.avro.io.DatumReader; import org.apache.avro.io.DecoderFactory; import org.apache.avro.io.EncoderFactory; diff --git a/lang/java/avro/src/test/java/org/apache/avro/io/TestBlockingDirectBinaryEncoder.java b/lang/java/avro/src/test/java/org/apache/avro/io/TestBlockingDirectBinaryEncoder.java index caf485500f0..e0221848745 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/io/TestBlockingDirectBinaryEncoder.java +++ b/lang/java/avro/src/test/java/org/apache/avro/io/TestBlockingDirectBinaryEncoder.java @@ -23,7 +23,6 @@ import org.apache.avro.generic.GenericDatumReader; import org.apache.avro.message.BinaryMessageDecoder; import org.apache.avro.specific.TestRecordWithMapsAndArrays; -import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import java.io.ByteArrayOutputStream; @@ -33,7 +32,6 @@ import java.util.Map; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.is; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; diff --git a/lang/java/avro/src/test/java/org/apache/avro/io/TestEncoders.java b/lang/java/avro/src/test/java/org/apache/avro/io/TestEncoders.java index df4ca4aeb02..24ad7bada08 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/io/TestEncoders.java +++ b/lang/java/avro/src/test/java/org/apache/avro/io/TestEncoders.java @@ -33,7 +33,6 @@ import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; @@ -42,7 +41,6 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import static java.util.Arrays.asList; diff --git a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java index d9e1bec4026..a2ae0ab7cf1 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java +++ b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java @@ -40,7 +40,6 @@ import org.apache.avro.AvroTypeException; import org.apache.avro.JsonProperties; import org.apache.avro.JsonSchemaParser; -import org.apache.avro.NameValidator; import org.apache.avro.Protocol; import org.apache.avro.Schema; import org.apache.avro.Schema.Field; diff --git a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflectData.java b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflectData.java index 40d9ad6decb..577b5172d45 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflectData.java +++ b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflectData.java @@ -19,7 +19,6 @@ package org.apache.avro.reflect; import org.apache.avro.AvroTypeException; -import org.apache.avro.JsonSchemaParser; import org.apache.avro.Protocol; import org.apache.avro.Schema; import org.apache.avro.SchemaParser; diff --git a/lang/java/avro/src/test/java/org/apache/avro/specific/TestRecordWithMapsAndArrays.java b/lang/java/avro/src/test/java/org/apache/avro/specific/TestRecordWithMapsAndArrays.java index 1ffe36b79d1..6287db1a1b9 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/specific/TestRecordWithMapsAndArrays.java +++ b/lang/java/avro/src/test/java/org/apache/avro/specific/TestRecordWithMapsAndArrays.java @@ -17,9 +17,6 @@ */ package org.apache.avro.specific; -import org.apache.avro.generic.GenericArray; -import org.apache.avro.specific.SpecificData; -import org.apache.avro.util.Utf8; import org.apache.avro.message.BinaryMessageEncoder; import org.apache.avro.message.BinaryMessageDecoder; import org.apache.avro.message.SchemaStore; diff --git a/lang/java/avro/src/test/java/org/apache/avro/specific/int$.java b/lang/java/avro/src/test/java/org/apache/avro/specific/int$.java index 2a1a1470f8f..1b01354263d 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/specific/int$.java +++ b/lang/java/avro/src/test/java/org/apache/avro/specific/int$.java @@ -5,7 +5,6 @@ */ package org.apache.avro.specific; -import com.fasterxml.jackson.databind.jsonschema.JsonSchema; import org.apache.avro.JsonSchemaParser; import org.apache.avro.message.BinaryMessageDecoder; import org.apache.avro.message.BinaryMessageEncoder; diff --git a/lang/java/compiler/src/test/java/org/apache/avro/specific/TestSpecificData.java b/lang/java/compiler/src/test/java/org/apache/avro/specific/TestSpecificData.java index 33a9205e453..744b5c65364 100644 --- a/lang/java/compiler/src/test/java/org/apache/avro/specific/TestSpecificData.java +++ b/lang/java/compiler/src/test/java/org/apache/avro/specific/TestSpecificData.java @@ -46,7 +46,6 @@ import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; -import org.apache.avro.JsonSchemaParser; import org.apache.avro.Schema; import org.apache.avro.SchemaParser; import org.apache.avro.compiler.specific.SpecificCompiler; diff --git a/lang/java/ipc-netty/src/test/java/org/apache/avro/ipc/netty/TestNettyServerWithSSL.java b/lang/java/ipc-netty/src/test/java/org/apache/avro/ipc/netty/TestNettyServerWithSSL.java index aafdd4f607a..9b969002f1b 100644 --- a/lang/java/ipc-netty/src/test/java/org/apache/avro/ipc/netty/TestNettyServerWithSSL.java +++ b/lang/java/ipc-netty/src/test/java/org/apache/avro/ipc/netty/TestNettyServerWithSSL.java @@ -20,7 +20,6 @@ import java.io.File; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.security.KeyStore; import java.security.Security; diff --git a/lang/java/ipc/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java b/lang/java/ipc/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java index 3ff7dd3c02b..98111a55ce8 100644 --- a/lang/java/ipc/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java +++ b/lang/java/ipc/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java @@ -49,11 +49,9 @@ import org.apache.avro.test.Kind; import org.apache.avro.compiler.specific.SpecificCompiler.OutputFile; -import org.junit.Rule; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.io.TempDir; -import org.junit.rules.TestName; public class TestSpecificCompiler { diff --git a/lang/java/maven-plugin/src/test/java/org/apache/avro/mojo/TestInduceMojo.java b/lang/java/maven-plugin/src/test/java/org/apache/avro/mojo/TestInduceMojo.java index 6c93a382233..00f0ac854ef 100644 --- a/lang/java/maven-plugin/src/test/java/org/apache/avro/mojo/TestInduceMojo.java +++ b/lang/java/maven-plugin/src/test/java/org/apache/avro/mojo/TestInduceMojo.java @@ -22,7 +22,6 @@ import java.util.Arrays; import org.apache.avro.Protocol; -import org.apache.avro.Schema; import org.apache.avro.SchemaParser; import org.apache.avro.entities.Person; import org.apache.avro.protocols.Remote; diff --git a/lang/java/maven-plugin/src/test/java/org/apache/avro/mojo/TestSchemaMojo.java b/lang/java/maven-plugin/src/test/java/org/apache/avro/mojo/TestSchemaMojo.java index f54b9a40403..918251c10b0 100644 --- a/lang/java/maven-plugin/src/test/java/org/apache/avro/mojo/TestSchemaMojo.java +++ b/lang/java/maven-plugin/src/test/java/org/apache/avro/mojo/TestSchemaMojo.java @@ -20,7 +20,6 @@ import org.apache.maven.plugin.MojoExecutionException; import org.codehaus.plexus.util.FileUtils; import org.junit.Test; -import org.junit.jupiter.api.Assertions; import java.io.File; import java.nio.file.Files; diff --git a/lang/java/pom.xml b/lang/java/pom.xml index 6991689808a..389b556198e 100644 --- a/lang/java/pom.xml +++ b/lang/java/pom.xml @@ -340,8 +340,7 @@ ${main.basedir}/lang/java/eclipse-java-formatter.xml 4.19 - - + Remove wildcard imports import\s+[^\*\s]+\*;(\r\n|\r|\n) From 3c323e75d802064ab01792dbe083ac5d13eb7ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Mej=C3=ADa?= Date: Fri, 22 May 2026 15:08:54 +0200 Subject: [PATCH 5/9] AVRO-4261: [Java] Remove pre-Java 17 workarounds and dead code - Remove MapUtil class (JDK-8161372 workaround fixed in JDK 9) - Fix non-static inner class detection in ReflectData to use Class.isMemberClass() instead of relying on synthetic this$0 field visibility, which is no longer guaranteed in JDK 21+ - Remove dead TestProtocolReflect.error() test (required JDK <= 11) - Remove commented-out tools.jar code in TestSpecificData (JDK 8 only) - Clean stale Unsafe/Android javadoc in ReflectionUtil - Remove obsolete 'Java 8+' qualifiers in AbstractAvroMojo javadoc - Update dependabot.yml Jetty comment to reflect actual blocker (javax -> jakarta migration, not JDK version) --- .github/dependabot.yml | 2 +- .../org/apache/avro/reflect/ReflectData.java | 8 ++-- .../apache/avro/reflect/ReflectionUtil.java | 6 +-- .../java/org/apache/avro/util/MapUtil.java | 46 ------------------- .../apache/avro/reflect/TestReflectData.java | 4 -- .../avro/specific/TestSpecificData.java | 17 ------- .../apache/avro/grpc/ServiceDescriptor.java | 5 +- .../org/apache/avro/TestProtocolReflect.java | 17 ------- .../apache/avro/mojo/AbstractAvroMojo.java | 7 ++- 9 files changed, 10 insertions(+), 102 deletions(-) delete mode 100644 lang/java/avro/src/main/java/org/apache/avro/util/MapUtil.java diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b11db2b271d..a511432de89 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -32,7 +32,7 @@ updates: interval: "weekly" day: "sunday" ignore: - # Jetty >= 10 requires JDK 11 + # Jetty >= 10 uses the Jakarta Servlet API; upgrading requires a javax -> jakarta migration - dependency-name: "org.eclipse.jetty:jetty-server" versions: - ">= 10.0.0" diff --git a/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java b/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java index 61e070b0525..a1158b2427d 100644 --- a/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java +++ b/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java @@ -69,8 +69,6 @@ /** Utilities to use existing Java classes and interfaces via reflection. */ public class ReflectData extends SpecificData { - private static final String STRING_OUTER_PARENT_REFERENCE = "this$0"; - // holds a wrapper so null entries will have a cached value private final ConcurrentMap encoderCache = new ConcurrentHashMap<>(); @@ -741,6 +739,9 @@ protected Schema createSchema(Type type, Map names) { schema = Schema.createRecord(name, doc, space, error); consumeAvroAliasAnnotation(c, schema); names.put(fullName, schema); + if (c.isMemberClass() && !Modifier.isStatic(c.getModifiers())) { + throw new AvroTypeException("Class " + fullName + " must be a static inner class"); + } for (Field field : getCachedFields(c)) if ((field.getModifiers() & (Modifier.TRANSIENT | Modifier.STATIC)) == 0 && !field.isAnnotationPresent(AvroIgnore.class)) { @@ -752,9 +753,6 @@ protected Schema createSchema(Type type, Map names) { AvroName annotatedName = field.getAnnotation(AvroName.class); // Rename fields String fieldName = (annotatedName != null) ? annotatedName.value() : field.getName(); - if (STRING_OUTER_PARENT_REFERENCE.equals(fieldName)) { - throw new AvroTypeException("Class " + fullName + " must be a static inner class"); - } Schema.Field recordField = new Schema.Field(fieldName, fieldSchema, doc, defaultValue); AvroMeta[] metadata = field.getAnnotationsByType(AvroMeta.class); // add metadata diff --git a/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectionUtil.java b/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectionUtil.java index 3221d91d1f2..f391d9a3aaf 100644 --- a/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectionUtil.java +++ b/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectionUtil.java @@ -34,11 +34,7 @@ import java.util.function.Supplier; /** - * A few utility methods for using @link{java.misc.Unsafe}, mostly for private - * use. - * - * Use of Unsafe on Android is forbidden, as Android provides only a very - * limited functionality for this class compared to the JDK version. + * Utility methods for reflective field access. * * InterfaceAudience.Private */ diff --git a/lang/java/avro/src/main/java/org/apache/avro/util/MapUtil.java b/lang/java/avro/src/main/java/org/apache/avro/util/MapUtil.java deleted file mode 100644 index 394aa2b3a63..00000000000 --- a/lang/java/avro/src/main/java/org/apache/avro/util/MapUtil.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - */ -package org.apache.avro.util; - -import java.util.concurrent.ConcurrentMap; -import java.util.function.Function; - -public class MapUtil { - - private MapUtil() { - super(); - } - - /** - * A temporary workaround for Java 8 specific performance issue JDK-8161372. - * - * @see JDK-8161372 - * @deprecated As of JDK 1.9 this issue has been resolved. - */ - // TODO: Remove for 1.13.0 or later - @Deprecated - public static V computeIfAbsent(ConcurrentMap map, K key, Function mappingFunction) { - V value = map.get(key); - if (value != null) { - return value; - } - return map.computeIfAbsent(key, mappingFunction::apply); - } - -} diff --git a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflectData.java b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflectData.java index 577b5172d45..16328af58c4 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflectData.java +++ b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflectData.java @@ -24,8 +24,6 @@ import org.apache.avro.SchemaParser; import org.apache.avro.util.internal.JacksonUtils; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledForJreRange; -import org.junit.jupiter.api.condition.JRE; import java.util.Arrays; import java.util.Collections; @@ -143,8 +141,6 @@ public class Definition { } @Test - // FIXME: Why does this test fail under JDK 21? - @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_17, disabledReason = "Doesn't work under JRE 21, no clue why") void nonStaticInnerClasses() { assertThrows(AvroTypeException.class, () -> { ReflectData.get().getSchema(Definition.class); diff --git a/lang/java/compiler/src/test/java/org/apache/avro/specific/TestSpecificData.java b/lang/java/compiler/src/test/java/org/apache/avro/specific/TestSpecificData.java index 744b5c65364..0d429f94b59 100644 --- a/lang/java/compiler/src/test/java/org/apache/avro/specific/TestSpecificData.java +++ b/lang/java/compiler/src/test/java/org/apache/avro/specific/TestSpecificData.java @@ -85,23 +85,6 @@ void separateThreadContextClassLoader() throws Exception { StandardJavaFileManager fileManager = javac.getStandardFileManager(null, null, null); Iterable units = fileManager.getJavaFileObjects("target/foo/Bar.java"); - JavaCompiler.CompilationTask task1 = javac.getTask(null, fileManager, null, null, null, units); - - // FIXME: This part uses JavacTask which makes it depend on the tools.jar and - // thus will only run in JDK 8 - // JavacTask jcTask = (JavacTask) task1; - - // Iterable analyze = jcTask.analyze(); - - // GeneratedCodeController ctrl = new GeneratedCodeController(); - // for (Element el : analyze) { - // if (el.getKind() == ElementKind.CLASS) { - // List accept = el.accept(ctrl, 0); - // assertTrue(accept.isEmpty(), - // accept.stream().collect(Collectors.joining("\n\t"))); - // } - // } - javac.getTask(null, fileManager, null, null, null, units).call(); fileManager.close(); diff --git a/lang/java/grpc/src/main/java/org/apache/avro/grpc/ServiceDescriptor.java b/lang/java/grpc/src/main/java/org/apache/avro/grpc/ServiceDescriptor.java index bfb8ec2de7a..0984473546f 100644 --- a/lang/java/grpc/src/main/java/org/apache/avro/grpc/ServiceDescriptor.java +++ b/lang/java/grpc/src/main/java/org/apache/avro/grpc/ServiceDescriptor.java @@ -24,7 +24,6 @@ import java.util.concurrent.ConcurrentMap; import io.grpc.MethodDescriptor; -import org.apache.avro.util.MapUtil; import static io.grpc.MethodDescriptor.generateFullMethodName; @@ -50,7 +49,7 @@ private ServiceDescriptor(Class iface, String serviceName) { */ public static ServiceDescriptor create(Class iface) { String serviceName = AvroGrpcUtils.getServiceName(iface); - return MapUtil.computeIfAbsent(SERVICE_DESCRIPTORS, serviceName, key -> new ServiceDescriptor(iface, serviceName)); + return SERVICE_DESCRIPTORS.computeIfAbsent(serviceName, key -> new ServiceDescriptor(iface, serviceName)); } /** @@ -68,7 +67,7 @@ public String getServiceName() { * @return a {@link MethodDescriptor} */ public MethodDescriptor getMethod(String methodName, MethodDescriptor.MethodType methodType) { - return MapUtil.computeIfAbsent(methods, methodName, + return methods.computeIfAbsent(methodName, key -> MethodDescriptor.newBuilder() .setFullMethodName(generateFullMethodName(serviceName, methodName)).setType(methodType) .setRequestMarshaller(new AvroRequestMarshaller(protocol.getMessages().get(methodName))) diff --git a/lang/java/ipc/src/test/java/org/apache/avro/TestProtocolReflect.java b/lang/java/ipc/src/test/java/org/apache/avro/TestProtocolReflect.java index dd763444138..1b61553342c 100644 --- a/lang/java/ipc/src/test/java/org/apache/avro/TestProtocolReflect.java +++ b/lang/java/ipc/src/test/java/org/apache/avro/TestProtocolReflect.java @@ -28,8 +28,6 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledForJreRange; -import org.junit.jupiter.api.condition.JRE; import static org.junit.jupiter.api.Assertions.*; @@ -145,21 +143,6 @@ void echoBytes() throws IOException { assertArrayEquals(data, echoed); } - @Test - // The JRE range is because reflection based protocols try to (among others) - // make the field Throwable.cause accessible, and are not allowed to. - @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_11, disabledReason = "Java 11 announced: All illegal access operations will be denied in a future release") - void error() throws IOException { - SimpleException error = null; - try { - proxy.error(); - } catch (SimpleException e) { - error = e; - } - assertNotNull(error); - assertEquals("foo", error.getMessage()); - } - @Test void undeclaredError() throws Exception { this.throwUndeclaredError = true; diff --git a/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java b/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java index 5615df36e3e..1de65a5e73e 100644 --- a/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java +++ b/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java @@ -149,8 +149,7 @@ public abstract class AbstractAvroMojo extends AbstractMojo { /** * The createOptionalGetters parameter enables generating the getOptional... - * methods that return an Optional of the requested type. This works ONLY on - * Java 8+ + * methods that return an Optional of the requested type. * * @parameter property="createOptionalGetters" */ @@ -158,7 +157,7 @@ public abstract class AbstractAvroMojo extends AbstractMojo { /** * The gettersReturnOptional parameter enables generating get... methods that - * return an Optional of the requested type. This works ONLY on Java 8+ + * return an Optional of the requested type. * * @parameter property="gettersReturnOptional" */ @@ -168,7 +167,7 @@ public abstract class AbstractAvroMojo extends AbstractMojo { * The optionalGettersForNullableFieldsOnly parameter works in conjunction with * gettersReturnOptional option. If it is set, Optional getters will be * generated only for fields that are nullable. If the field is mandatory, - * regular getter will be generated. This works ONLY on Java 8+. + * regular getter will be generated. * * @parameter property="optionalGettersForNullableFieldsOnly" */ From 05da92b4ec9316d404140e7585bb61a8d15bf7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Mej=C3=ADa?= Date: Fri, 22 May 2026 15:11:51 +0200 Subject: [PATCH 6/9] AVRO-4261: [Java] Replace deprecated Class.newInstance() calls Replace Class.newInstance() (deprecated since Java 9) with getDeclaredConstructor().newInstance() in Perf.java and ThriftData.java. Also remove stale 'Java 8' qualifier from SpecificCompiler javadoc. --- .../org/apache/avro/compiler/specific/SpecificCompiler.java | 2 +- lang/java/ipc/src/test/java/org/apache/avro/io/Perf.java | 6 +++--- .../src/main/java/org/apache/avro/thrift/ThriftData.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java index ea1e1a11b55..17d153bd429 100644 --- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java +++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java @@ -1225,7 +1225,7 @@ public static String generateGetMethod(Schema schema, Field field) { } /** - * Generates the name of a field accessor method that returns a Java 8 Optional. + * Generates the name of a field accessor method that returns an Optional. * * @param schema the schema in which the field is defined. * @param field the field for which to generate the accessor name. diff --git a/lang/java/ipc/src/test/java/org/apache/avro/io/Perf.java b/lang/java/ipc/src/test/java/org/apache/avro/io/Perf.java index cb01dd7fed8..9111a7fdf07 100644 --- a/lang/java/ipc/src/test/java/org/apache/avro/io/Perf.java +++ b/lang/java/ipc/src/test/java/org/apache/avro/io/Perf.java @@ -194,13 +194,13 @@ public static void main(String[] args) throws Exception { String a = args[i]; TestDescriptor t = ALL_TESTS.get(a); if (null != t) { - tests.add(t.test.newInstance()); + tests.add(t.test.getDeclaredConstructor().newInstance()); continue; } List lt = BATCHES.get(a); if (null != lt) { for (TestDescriptor td : lt) { - tests.add(td.test.newInstance()); + tests.add(td.test.getDeclaredConstructor().newInstance()); } continue; } @@ -257,7 +257,7 @@ public static void main(String[] args) throws Exception { if (tests.isEmpty()) { for (Map.Entry entry : ALL_TESTS.entrySet()) { TestDescriptor t = entry.getValue(); - Test test = t.test.newInstance(); + Test test = t.test.getDeclaredConstructor().newInstance(); tests.add(test); } } diff --git a/lang/java/thrift/src/main/java/org/apache/avro/thrift/ThriftData.java b/lang/java/thrift/src/main/java/org/apache/avro/thrift/ThriftData.java index 3b82a0ceba5..451b1bf6ce9 100644 --- a/lang/java/thrift/src/main/java/org/apache/avro/thrift/ThriftData.java +++ b/lang/java/thrift/src/main/java/org/apache/avro/thrift/ThriftData.java @@ -163,7 +163,7 @@ public Object newRecord(Object old, Schema schema) { return super.newRecord(old, schema); // punt to generic if (c.isInstance(old)) return old; // reuse instance - return c.newInstance(); // create new instance + return c.getDeclaredConstructor().newInstance(); // create new instance } catch (Exception e) { throw new RuntimeException(e); } From 83150892c3acbfb8c2d9f0e4abb3f9653522bbea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Mej=C3=ADa?= Date: Fri, 22 May 2026 16:48:40 +0200 Subject: [PATCH 7/9] AVRO-4261: [Java] Remove -Djava.security.manager=allow from surefire argLine The Security Manager was permanently removed in JDK 24 (JEP 486). On JDK 25, passing -Djava.security.manager=allow causes the forked JVM to exit immediately with code 1, crashing all tests in trevni, mapred, and tools modules. This flag was originally added as a workaround for JDK 17-23 where Subject.getSubject(AccessControlContext) throws UnsupportedOperationException unless the security manager is explicitly allowed. Hadoop's UserGroupInformation was the caller of Subject.getSubject() via its security layer. Avro itself has no direct calls to Subject.getSubject() or Subject.doAs(). Hadoop 3.4.3 already handles this internally through its SubjectUtil class which uses MethodHandle-based dispatch at class initialization time: - On JDK 18+: resolves Subject.current() and Subject.callAs() directly - On JDK 17: falls back to AccessController.getContext() + Subject.getSubject() Since Hadoop figures out the right API at runtime, the flag is no longer needed for any JDK version we support (17, 21, 25). --- lang/java/mapred/pom.xml | 2 -- lang/java/tools/pom.xml | 2 -- lang/java/trevni/pom.xml | 2 -- pom.xml | 2 +- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/lang/java/mapred/pom.xml b/lang/java/mapred/pom.xml index 4b3f5e544ef..08ae3d04c39 100644 --- a/lang/java/mapred/pom.xml +++ b/lang/java/mapred/pom.xml @@ -92,8 +92,6 @@ 1 false none - - -Djava.security.manager=allow diff --git a/lang/java/tools/pom.xml b/lang/java/tools/pom.xml index 50f1bae2a8b..b0697f8845a 100644 --- a/lang/java/tools/pom.xml +++ b/lang/java/tools/pom.xml @@ -165,8 +165,6 @@ 1 false none - - -Djava.security.manager=allow diff --git a/lang/java/trevni/pom.xml b/lang/java/trevni/pom.xml index 64fd16c10f6..1a1e8581acb 100644 --- a/lang/java/trevni/pom.xml +++ b/lang/java/trevni/pom.xml @@ -55,8 +55,6 @@ 1 false none - - -Djava.security.manager=allow diff --git a/pom.xml b/pom.xml index cbe5587dd0e..890bb1b4f0e 100644 --- a/pom.xml +++ b/pom.xml @@ -248,7 +248,7 @@ - 21 + 17 [3.9.6,) From 46ae2684fbb9b9ceab67da0a8b82fcb7f5911880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Mej=C3=ADa?= Date: Fri, 22 May 2026 18:14:39 +0200 Subject: [PATCH 8/9] AVRO-4261: [Java] Remove Hadoop 2 backwards compatibility testing --- lang/java/build.sh | 2 -- .../apache/avro/mapreduce/AvroOutputFormatBase.java | 12 +----------- lang/java/pom.xml | 7 ------- 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/lang/java/build.sh b/lang/java/build.sh index 5020a6ed0ca..c72b93bf70e 100755 --- a/lang/java/build.sh +++ b/lang/java/build.sh @@ -33,8 +33,6 @@ main() { ;; test) mvn -B verify - # Test the modules that depend on hadoop using Hadoop 2 - mvn -Dmaven.build.cache.enabled=false -B test -Phadoop2 ;; dist) mvn -P dist package -DskipTests javadoc:aggregate diff --git a/lang/java/mapred/src/main/java/org/apache/avro/mapreduce/AvroOutputFormatBase.java b/lang/java/mapred/src/main/java/org/apache/avro/mapreduce/AvroOutputFormatBase.java index 5aa84b341d8..c1a8724b7c2 100644 --- a/lang/java/mapred/src/main/java/org/apache/avro/mapreduce/AvroOutputFormatBase.java +++ b/lang/java/mapred/src/main/java/org/apache/avro/mapreduce/AvroOutputFormatBase.java @@ -20,9 +20,7 @@ import java.io.IOException; import java.io.OutputStream; -import org.apache.hadoop.mapreduce.OutputCommitter; -import org.apache.avro.AvroRuntimeException; import org.apache.avro.file.CodecFactory; import org.apache.avro.file.DataFileConstants; import org.apache.avro.hadoop.file.HadoopCodecFactory; @@ -87,15 +85,7 @@ protected static CodecFactory getCompressionCodec(TaskAttemptContext context) { } private Path getWorkPathFromCommitter(TaskAttemptContext context) throws IOException { - // When Hadoop 2 support is dropped, this method removed to a simple cast - // See https://github.com/apache/avro/pull/1431/ - OutputCommitter committer = getOutputCommitter(context); - try { - return (Path) committer.getClass().getMethod("getWorkPath").invoke(committer); - } catch (ReflectiveOperationException e) { - throw new AvroRuntimeException( - "Committer: " + committer.getClass().getName() + " does not have method getWorkPath", e); - } + return ((org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter) getOutputCommitter(context)).getWorkPath(); } /** diff --git a/lang/java/pom.xml b/lang/java/pom.xml index 389b556198e..6222151cc24 100644 --- a/lang/java/pom.xml +++ b/lang/java/pom.xml @@ -499,13 +499,6 @@ - - - hadoop2 - - 2.10.1 - - - 17 17 ${project.basedir} dist