Skip to content

[IcebergIO] Raise Java 17 floor for IcebergIO's Java 11 dependents#39064

Open
peterphitran wants to merge 5 commits into
apache:masterfrom
peterphitran:iceberg-java17-floor
Open

[IcebergIO] Raise Java 17 floor for IcebergIO's Java 11 dependents#39064
peterphitran wants to merge 5 commits into
apache:masterfrom
peterphitran:iceberg-java17-floor

Conversation

@peterphitran

@peterphitran peterphitran commented Jun 22, 2026

Copy link
Copy Markdown

Addresses #38925 (preparatory PR1a of 2).

What changes

Raises the Java floor for IcebergIO and its dependent modules from 11 to 17, in preparation for the upcoming Iceberg 1.11.0 upgrade (PR1b). Iceberg 1.11.0 is published as Java 17 bytecode and drops Java 11, so the floor has to move first. Splitting the floor raise into its own self-contained, CI-green PR keeps the dependency bump (PR1b) minimal and lets CI validate the Java 17 floor independently.

requireJavaVersion 11 → 17 (Gradle's JVM-version variant resolution will not let a Java 11 module depend on a Java 17 one, so these must move together):

  • sdks/java/io/iceberg/build.gradle
  • sdks/java/extensions/sql/iceberg/build.gradle (depends on the IcebergIO module)
  • examples/java/iceberg/build.gradle (depends on the IcebergIO module)

CI workflows — the five IO_Iceberg_* GitHub Actions workflows now set java-version: 17 (they otherwise default to 11 via setup-environment-action), matching the Delta and Debezium IO workflows:

  • .github/workflows/IO_Iceberg_Unit_Tests.yml
  • .github/workflows/IO_Iceberg_Integration_Tests.yml
  • .github/workflows/IO_Iceberg_Integration_Tests_Dataflow.yml
  • .github/workflows/IO_Iceberg_Managed_Integration_Tests_Dataflow.yml
  • .github/workflows/IO_Iceberg_Performance_Tests.yml

Checker Framework skipUses/skipDefs regex (buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy) — with requireJavaVersion: 17, on a Java 11 build host (e.g. CI) IcebergIO is compiled by a forked Java 17 javac launched via java17Home, and Gradle passes its arguments through an @argfile. The backslash-escaped \. in Beam's Checker -AskipUses/-AskipDefs regexes does not survive that round-trip, so ^org\.slf4j\.Logger.* becomes a literal-backslash regex that matches nothing and the org.slf4j.Logger nullness suppression is silently dropped — making two latent Logger.info(@Nullable) calls in IcebergIO hard-error under the NullnessChecker. Switching the hardcoded skipUses/skipDefs regexes to the backslash-free character class [.] (semantically identical to \.) makes them survive the @argfile round-trip. Behavior is unchanged on the in-process compile path, and this fixes the suppression for any module that forks to a newer JDK. IcebergIO is the first Checker-enabled module to compile via an external-JDK fork, which is why it surfaced here.

Cross-language wrapper validation on Java 17createCrossLanguageUsingJavaExpansionTask (same file) was missing the JAVA_HOME redirect that #38974 added to the other cross-language task factories; the bundled (now Java 17) IcebergIO jar otherwise fails to launch from Python with UnsupportedClassVersionError. The launch JDK is resolved from -PtestJavaVersion (java${ver}Home), matching the other factories, and the precommit passes -PtestJavaVersion=17:

  • .github/workflows/beam_PreCommit_Xlang_Generated_Transforms.yml

What does NOT change

  • No dependency bump here. iceberg_version stays at 1.10.0; the bump to 1.11.0 is PR1b (stacked on this PR).
  • The Java IO expansion-service module (sdks/java/io/expansion-service) is already Java 17 on master (Roll forward io expansion service to Java17 #38974), so its build needs no change — only the cross-language launch wiring did (see above).
  • No public API change. IcebergIO is internal, exposed only via Managed.read(ICEBERG) / Managed.write(ICEBERG).

Breaking change

Pipelines using Managed.read(ICEBERG) / Managed.write(ICEBERG), and Beam SQL's IcebergIO extension, now require a Java 17+ JVM. (The cross-language expansion service already required Java 17 as of #38974.) Documented in CHANGES.md.

Verification

  • :sdks:java:io:iceberg:compileJava and the dependent modules compile on JDK 17, including the forked Java 17 compile path taken on a Java 11 host (validated with a clean --rerun-tasks build).
  • With the [.] skipUses fix the forked compile is green; reverting it reproduces the two Logger.info(@Nullable) [argument] errors — confirming the root cause is the @argfile round-trip, not Java 17 itself.
  • The cross-language wrapper validation launches the expansion service on Java 17.
  • The five updated IO_Iceberg_* workflows run on Java 17.

Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:

  • Mention the appropriate issue in your description (for example: addresses #123).
  • Update CHANGES.md with noteworthy changes.
  • If this contribution is large, please file an Apache Individual Contributor License Agreement.

peterphitran and others added 2 commits June 22, 2026 15:39
Iceberg 1.11.0 is published as Java 17 bytecode (class file version 61);
Gradle module metadata declares "org.gradle.jvm.version": 17. The current
Java 11 floor on sdks/java/io/iceberg causes Iceberg 1.11.0 artifacts
to fail resolution. Raise the floor independently so the version bump
is a clean diff.

Iceberg 1.10.0 still resolves under Java 17 (10.0 only requires Java 11+).

Tracks apache#38925.
Iceberg 1.11.0 dropped Java 11 support and this branch raised the iceberg
module floor to Java 17 (requireJavaVersion VERSION_17). The IO_Iceberg_*
workflows call setup-environment-action without a java-version, which
defaults to Java 11, so the module would fail to build or be disabled on
CI. Pin these workflows to Java 17, matching the Delta and Debezium IO
workflows.

For apache#38925

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request serves as a preparatory step for upgrading the Iceberg dependency to version 1.11.0, which requires Java 17. By raising the Java floor for the IcebergIO module and its dependents now, the project ensures a stable transition and allows for independent CI validation of the new environment requirements.

Highlights

  • Java Version Upgrade: Raised the minimum Java version requirement from 11 to 17 for IcebergIO and its dependent modules (SQL extension and examples) to support upcoming Iceberg 1.11.0 requirements.
  • CI Workflow Updates: Updated five Iceberg-related GitHub Actions workflows to use Java 17 for testing and integration environments.
  • Documentation: Updated CHANGES.md to reflect the new Java 17 runtime requirement for IcebergIO pipelines and the SQL extension.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Ignored Files
  • Ignored by pattern: .github/workflows/** (5)
    • .github/workflows/IO_Iceberg_Integration_Tests.yml
    • .github/workflows/IO_Iceberg_Integration_Tests_Dataflow.yml
    • .github/workflows/IO_Iceberg_Managed_Integration_Tests_Dataflow.yml
    • .github/workflows/IO_Iceberg_Performance_Tests.yml
    • .github/workflows/IO_Iceberg_Unit_Tests.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the minimum Java version requirement for Apache Beam's IcebergIO module, its SQL extension, and its examples from Java 11 to Java 17. This change is documented in the release notes. Feedback suggests restoring the accidentally removed trailing newline at the end of CHANGES.md.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread CHANGES.md Outdated
## Highlights

- For versions 2.19.0 and older release notes are available on [Apache Beam Blog](https://beam.apache.org/blog/).
- For versions 2.19.0 and older release notes are available on [Apache Beam Blog](https://beam.apache.org/blog/). No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The trailing newline at the end of the file was accidentally removed. It is recommended to keep a trailing newline at the end of markdown files to adhere to POSIX standards and avoid git diff warnings.

Suggested change
- For versions 2.19.0 and older release notes are available on [Apache Beam Blog](https://beam.apache.org/blog/).
- For versions 2.19.0 and older release notes are available on [Apache Beam Blog](https://beam.apache.org/blog/).

Bumping the iceberg module to Java 17 (Iceberg 1.11.0 dropped Java 11)
breaks the Java 11 modules that depend on it, because Gradle's
JVM-version variant resolution refuses to let a Java 11 consumer depend
on a Java 17 library. Raise requireJavaVersion 11 -> 17 in:

  - sdks/java/extensions/sql/iceberg
  - examples/java/iceberg

The Java IO expansion service (sdks/java/io/expansion-service) also
depends on IcebergIO but was already raised to Java 17 on master in
apache#38974 (for Delta Lake), so it needs no change here.

For apache#38925

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@peterphitran peterphitran force-pushed the iceberg-java17-floor branch from 89f06e8 to 4f26daf Compare June 22, 2026 21:24
@github-actions

Copy link
Copy Markdown
Contributor

Checks are failing. Will not request review until checks are succeeding. If you'd like to override that behavior, comment assign set of reviewers

@peterphitran peterphitran force-pushed the iceberg-java17-floor branch from 0cb5db7 to f264257 Compare June 23, 2026 01:43
@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 57.73%. Comparing base (eaba570) to head (2a10ca8).
⚠️ Report is 12 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master   #39064      +/-   ##
============================================
+ Coverage     54.24%   57.73%   +3.48%     
- Complexity     1715    13050   +11335     
============================================
  Files          1064     2513    +1449     
  Lines        166935   261551   +94616     
  Branches       1255    10740    +9485     
============================================
+ Hits          90562   150997   +60435     
- Misses        74158   104824   +30666     
- Partials       2215     5730    +3515     
Flag Coverage Δ
java 64.20% <ø> (-3.40%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

Copy link
Copy Markdown
Contributor

Assigning reviewers:

R: @kennknowles for label java.
R: @Abacn for label build.

Note: If you would like to opt out of this review, comment assign to next reviewer.

Available commands:

  • stop reviewer notifications - opt out of the automated review tooling
  • remind me after tests pass - tag the comment author after tests pass
  • waiting on author - shift the attention set back to the author (any comment or push by the author will return the attention set to the reviewers)

The PR bot will only process comments in the main thread (not review comments).

@ahmedabu98 ahmedabu98 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @Abacn -- does this warrant making an expansion service just for IcebergIO? Similar to Debezium

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary change

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary change

// to java17Home when provided. Some bundled IOs (e.g. IcebergIO) are compiled for Java 17, so
// the expansion service must run on a JDK that can load them.
String testJavaHome = ver ? project.findProperty("java${ver}Home") : null
String expansionServiceJavaHome = testJavaHome ?: project.findProperty('java17Home')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be project.findProperty("java${ver}Home") ?

@Abacn Abacn Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be project.findProperty("java${ver}Home") ?

Yeah we should just use "java${ver}Home" or the current java

otherwise fall back to java17Home when provided. Some bundled IOs

fallback to a specific java sounds unusual. We should make sure testJavaHome is passed by workflow call or change the java version exercised by xlang tests

@peterphitran

Copy link
Copy Markdown
Author

@ahmedabu98 thank you for the feedback and for bringing up these cleaner solutions, my regards as I didn't scope things as well as I should have. I'll wait for @Abacn's call on the dedicated expansion service, but I definitely see the long-term benefit of that route

as for the other "unnecessary" changes and the logger you're right, I scoped those for the sake of simplicity, I can revert them and look into why the suppression drops on that compile path, so the fix lands in the right place rather than in the connector source

@Abacn

Abacn commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

cc @Abacn -- does this warrant making an expansion service just for IcebergIO? Similar to Debezium

Current approach is fine, IO expansion service is already on Java17 after #38974

Raising the Java 17 floor routes IcebergIO through a forked compile: on an older host JDK (e.g. Java 11 CI) the module is compiled by a separate Java 17 javac launched via java17Home, and Gradle passes its arguments through an @argfile. The backslash-escaped '\.' in Beam's Checker Framework -AskipUses and -AskipDefs regexes does not survive that @argfile round-trip, so '^org\.slf4j\.Logger.*' becomes a literal-backslash regex that matches nothing and the org.slf4j.Logger nullness suppression is silently dropped. Two latent Logger.info(@nullable) calls in IcebergIO then hard-error under the NullnessChecker.

Use the backslash-free character class '[.]' (semantically identical to '\.') so the regexes survive the @argfile round-trip. This fixes the suppression for every module that forks to a newer JDK, with no behavior change on the in-process compile path.
The cross-language wrapper validation launches the io expansion-service jar from Python via JAVA_HOME. That jar bundles IcebergIO, now Java 17 bytecode, so launching it on the default Java 11 fails with UnsupportedClassVersionError.

createCrossLanguageUsingJavaExpansionTask was missing the JAVA_HOME redirect that apache#38974 added to the other cross-language task factories. Add it, driven by -PtestJavaVersion (resolving java\Home), and pass -PtestJavaVersion=17 in the Xlang_Generated_Transforms precommit so the expansion service runs on a JDK that can load the bundled Java 17 IOs.
@peterphitran peterphitran force-pushed the iceberg-java17-floor branch from f264257 to 2a10ca8 Compare June 24, 2026 05:32
@peterphitran

Copy link
Copy Markdown
Author

@ahmedabu98 @Abacn updated based on the feedback (full details in the PR description):

Dropped the String.valueOf wrapping, found the issue was a build-infra bug: on a Java 11 host, the forked Java 17 compile passes javac args via an @argfile, and the . in Beam's Checker skipUses regex gets mangled in transit, silently dropping the Logger nullness suppression. Fixed in BeamModulePlugin by using [.] instead of . (same meaning, no backslash to mangle). The IO source is back to plain LOG.info(...). xlang launch now uses java${ver}Home (via -PtestJavaVersion) instead of hardcoded java17.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants