Skip to content

fix(bundle): relocate the AWS SDK bundled into hudi-utilities-bundle - #19425

Open
rahil-c wants to merge 2 commits into
apache:masterfrom
rahil-c:fix/utilities-bundle-relocate-awssdk
Open

fix(bundle): relocate the AWS SDK bundled into hudi-utilities-bundle#19425
rahil-c wants to merge 2 commits into
apache:masterfrom
rahil-c:fix/utilities-bundle-relocate-awssdk

Conversation

@rahil-c

@rahil-c rahil-c commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Change Logs

Summary. hudi-utilities-bundle doesn't shade the AWS SDK that JsonKinesisSource needs, so the published bundle jar can't actually run JsonKinesisSource on its own.

hudi-utilities depends on software.amazon.awssdk:kinesis and com.amazonaws:amazon-kinesis-deaggregator for JsonKinesisSource/KinesisOffsetGen/KinesisDeaggregator, but packaging/hudi-utilities-bundle/pom.xml's shade includes never picked either up. Neither artifact ends up in the shaded jar, so a deployment running only hudi-utilities-bundle hits NoClassDefFoundError on any software.amazon.awssdk.services.kinesis.* class the moment JsonKinesisSource is used.

hudi-aws-bundle already relocates its AWS SDK dependencies the same way this PR relocates hudi-utilities-bundle's: moving the software.amazon.awssdk package prefix to org.apache.hudi.software.amazon.awssdk, avoiding a classpath collision with whatever SDK version a consuming application has pinned on its own classpath.

Include list is scoped to kinesis/sts, not a wildcard. kinesis/sts aren't self-contained — they're thin client artifacts that depend on a shared set of AWS SDK v2 core libraries to actually load: KinesisClient implements AwsClient, which lives in the separate aws-core artifact; both need sdk-core for request handling, auth for signing, regions, http-client-spi plus apache-client/netty-nio-client for transport, and so on down the chain. None of that is optional — omit any of it and the class fails to load at runtime.

hudi-utilities also depends on hudi-aws (for Glue sync, the DynamoDB lock provider, and CloudWatch metrics elsewhere in hudi-utilities), which transitively resolves s3, dynamodb, glue, cloudwatch, and their protocol/support artifacts. A software.amazon.awssdk:* wildcard include would sweep those into this bundle too, even though JsonKinesisSource never touches them and hudi-aws's own classes aren't part of this bundle — so they'd just be dead weight (measured at ~17.7MB on the built jar).

Instead, the include list enumerates exactly the kinesis+sts transitive closure, traced with mvn dependency:tree -Dverbose against hudi-utilities: the shared AWS SDK v2 core (sdk-core, aws-core, auth, regions, http-client-spi, apache-client, netty-nio-client, checksums, retries, and their -spi siblings), kinesis's own protocol dependencies (aws-cbor-protocol, third-party-jackson-dataformat-cbor and -core), sts's (aws-query-protocol, profiles), and org.reactivestreams:reactive-streams, which sdk-core needs and isn't in the software.amazon.awssdk group (so a group-scoped wildcard wouldn't have covered it either).

Impact

hudi-utilities-bundle now carries the kinesis/sts dependency closure JsonKinesisSource needs, relocated under org.apache.hudi.software.amazon.awssdk.**. No behavior change for anything not using JsonKinesisSource.

Risk level

Low. Additive to the bundle's shaded contents; no existing classes move or change behavior.

The one thing worth double-checking on the built artifact is AWS SDK v2's ServiceLoader-based HTTP client discovery, since KinesisOffsetGen.createKinesisClient builds a KinesisClient without an explicit .httpClient(...). Verified locally that the relocated jar carries the rewritten service file, META-INF/services/org.apache.hudi.software.amazon.awssdk.http.SdkHttpService, containing org.apache.hudi.software.amazon.awssdk.http.apache.ApacheSdkHttpService.

Documentation Update

None. No configs, public API, or user-facing behavior change.

Contributor's checklist

  • Read through contributor's guide
  • Change Logs and Impact were stated clearly
  • Adequate tests were added if applicable — packaging-only change, no unit-test surface.
  • mvn -pl packaging/hudi-utilities-bundle -am package -DskipTests -Dscala-2.12 -Dspark3.5 -Dflink1.20 succeeds locally. Verified the resulting jar: zero classes remain at the original software/amazon/awssdk/** paths; the relocated SdkHttpService services file is present; s3/dynamodb/glue/cloudwatch/sqs/arns/aws-xml-protocol/crt-core are all absent; and JsonKinesisSource's own bytecode resolves to the relocated KinesisClient.
  • CI passed

JsonKinesisSource depends on software.amazon.awssdk:kinesis and
com.amazonaws:amazon-kinesis-deaggregator, but hudi-utilities-bundle's
shade config never included either, so the published bundle jar doesn't
carry the classes JsonKinesisSource needs at runtime.

hudi-aws-bundle already solves this exact problem for its own AWS
dependencies: it includes software.amazon.awssdk:* and relocates it to
org.apache.hudi.software.amazon.awssdk, avoiding classpath collisions
with whatever SDK version a consuming application pins. Apply the same
include + relocation to hudi-utilities-bundle so JsonKinesisSource works
when the bundle is deployed on its own.

Verified locally: `mvn -pl packaging/hudi-utilities-bundle -am package`
succeeds, and the resulting jar has zero classes at the original
software/amazon/awssdk/** paths (fully relocated under
org/apache/hudi/software/amazon/awssdk/**), including the relocated
META-INF/services/*SdkHttpService entries needed for the SDK's
ServiceLoader-based HTTP client discovery.
@github-actions github-actions Bot added the size:XS PR with lines of changes in <= 10 label Jul 30, 2026
@rahil-c rahil-c changed the title fix(bundle): shade and relocate the AWS SDK in hudi-utilities-bundle fix(bundle): relocate the AWS SDK bundled into hudi-utilities-bundle Jul 30, 2026
@codecov-commenter

codecov-commenter commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 75.55%. Comparing base (633d142) to head (4b108ef).
⚠️ Report is 60 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master   #19425      +/-   ##
============================================
- Coverage     75.56%   75.55%   -0.01%     
- Complexity    32651    32662      +11     
============================================
  Files          2574     2574              
  Lines        142995   142995              
  Branches      17530    17530              
============================================
- Hits         108051   108045       -6     
- Misses        26908    26915       +7     
+ Partials       8036     8035       -1     
Components Coverage Δ
hudi-common 82.26% <ø> (-0.02%) ⬇️
hudi-client 81.81% <ø> (-0.03%) ⬇️
hudi-flink 84.03% <ø> (ø)
hudi-spark-datasource 68.34% <ø> (+<0.01%) ⬆️
hudi-utilities 71.22% <ø> (+0.02%) ⬆️
hudi-cli 15.32% <ø> (ø)
hudi-hadoop 63.49% <ø> (ø)
hudi-sync 70.72% <ø> (ø)
hudi-io 79.57% <ø> (ø)
hudi-timeline-service 84.23% <ø> (+0.78%) ⬆️
hudi-cloud 64.00% <ø> (ø)
hudi-kafka-connect 53.20% <ø> (-0.77%) ⬇️
Flag Coverage Δ
common-and-other-modules 49.22% <ø> (-0.01%) ⬇️
flink-integration-tests 48.84% <ø> (-0.02%) ⬇️
hadoop-mr-java-client 43.38% <ø> (+0.05%) ⬆️
integration-tests 13.63% <ø> (+<0.01%) ⬆️
spark-client-hadoop-common 48.71% <ø> (ø)
spark-java-tests 51.41% <ø> (+0.01%) ⬆️
spark-scala-tests 46.08% <ø> (-0.01%) ⬇️
utilities 36.64% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.
see 17 files with indirect coverage changes

🚀 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.

@hudi-agent hudi-agent 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.

⚠️ 🤖 This review was generated by an AI agent and may contain mistakes. Please verify any suggestions before applying.

Thanks for working on this! This PR shades the AWS SDK v2 classes (relocated under org.apache.hudi.software.amazon.awssdk.**) plus the Kinesis deaggregator into hudi-utilities-bundle so JsonKinesisSource can run standalone, mirroring hudi-aws-bundle. The relocation of software.amazon.awssdk.* looks consistent with the source imports, but there's one bundling gap worth double-checking on the built artifact (see inline). Please take a look at the inline comment, and this should be ready for a Hudi committer or PMC member to take it from here.

<!-- AWS SDK for JsonKinesisSource; relocated below, matching hudi-aws-bundle. -->
<include>software.amazon.awssdk:*</include>
<!-- KPL de-aggregation: extracts user records from Kinesis Producer Library aggregated records -->
<include>com.amazonaws:amazon-kinesis-deaggregator</include>

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.

🤖 This includes amazon-kinesis-deaggregator but not com.amazonaws:amazon-kinesis-client. KinesisDeaggregator imports com.amazonaws.services.kinesis.clientlibrary.types.UserRecord, which lives in amazon-kinesis-client (pulled in transitively at 1.8.8), not in the deaggregator artifact — so the standalone bundle would still hit NoClassDefFoundError on UserRecord. Note hudi-aws-bundle includes both amazon-kinesis-deaggregator and amazon-kinesis-client. Could you add the amazon-kinesis-client include here to match?

⚠️ AI-generated; verify before applying. React 👍/👎 to flag quality.

software.amazon.awssdk:* also pulled in s3, dynamodb, glue, cloudwatch,
and their protocol/support artifacts -- none of which JsonKinesisSource
uses. Those come from other AWS-dependent code in hudi-utilities'
dependency graph, not from Kinesis. Since that code isn't part of this
bundle, the extra SDK surface was dead weight: ~17.7MB with nothing in
the shaded jar actually calling it.

Replaced the wildcard with the exact kinesis+sts transitive closure,
verified via `mvn dependency:tree -Dverbose`: the shared AWS SDK v2
core (sdk-core, aws-core, auth, regions, etc.), kinesis's own protocol
dependencies (aws-cbor-protocol, third-party-jackson-*), sts's
(aws-query-protocol, profiles), and org.reactivestreams, which sdk-core
needs and isn't in the software.amazon.awssdk group.

Verified locally: the resulting jar has zero classes from
s3/dynamodb/glue/cloudwatch/sqs/arns/aws-xml-protocol/crt-core, is
still fully self-resolving (zero unrelocated
software/amazon/awssdk/** classes), and JsonKinesisSource's bytecode
still resolves to the relocated KinesisClient.
@github-actions github-actions Bot added size:S PR with lines of changes in (10, 100] and removed size:XS PR with lines of changes in <= 10 labels Jul 30, 2026
@hudi-bot

Copy link
Copy Markdown
Collaborator

CI report:

Bot commands @hudi-bot supports the following commands:
  • @hudi-bot run azure re-run the last Azure build

@hudi-agent hudi-agent 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.

⚠️ 🤖 This review was generated by an AI agent and may contain mistakes. Please verify any suggestions before applying.

Thanks for the update! The reworked include list replaces the software.amazon.awssdk:* wildcard with an explicit set of AWS SDK v2 modules (core, kinesis, sts, and their protocol/transport dependencies), which is a reasonable way to keep the shaded set tight. One prior finding still looks open, though: the bundle adds com.amazonaws:amazon-kinesis-deaggregator but not com.amazonaws:amazon-kinesis-client, and KinesisDeaggregator still imports UserRecord from the latter — see the inline comment. Also worth double-checking that the now-explicit v2 include list is complete against the dependency tree so nothing needed gets dropped from the shaded jar. Please take a look at the inline comment, and this should be ready for a Hudi committer or PMC member to take it from here.

<include>software.amazon.awssdk:aws-query-protocol</include>
<include>software.amazon.awssdk:profiles</include>
<!-- KPL de-aggregation: extracts user records from Kinesis Producer Library aggregated records -->
<include>com.amazonaws:amazon-kinesis-deaggregator</include>

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.

🤖 The reworked list still only adds amazon-kinesis-deaggregator, not com.amazonaws:amazon-kinesis-client. KinesisDeaggregator imports com.amazonaws.services.kinesis.clientlibrary.types.UserRecord, which lives in amazon-kinesis-client (not the deaggregator jar), so the standalone bundle would still hit NoClassDefFoundError on UserRecord. hudi-aws-bundle includes both — could you add <include>com.amazonaws:amazon-kinesis-client</include> here to match?

⚠️ AI-generated; verify before applying. React 👍/👎 to flag quality.

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

Labels

size:S PR with lines of changes in (10, 100]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants