Skip to content

feat: Add GraalVM native-image support by removing Guava shading#617

Closed
alexcol23 wants to merge 1 commit into
splitio:masterfrom
AdelanteFinancialHoldings:graalvm-native-image-support
Closed

feat: Add GraalVM native-image support by removing Guava shading#617
alexcol23 wants to merge 1 commit into
splitio:masterfrom
AdelanteFinancialHoldings:graalvm-native-image-support

Conversation

@alexcol23

Copy link
Copy Markdown

This commit enables GraalVM native-image compilation for applications using the Split.io Java SDK.

Problem:
The Split SDK shades Guava to split.com.google.common.* to avoid dependency conflicts. However, this shaded Guava lacks the GraalVM native-image configuration that standard Guava provides, causing build failures with errors like:
'Discovered unresolved type: split.com.google.common.util.concurrent.SettableFuture'

Root Cause:
Standard Guava (com.google.common.) includes GraalVM native-image configuration in META-INF/native-image/. When the SDK shades Guava to split.com.google.common., this configuration is lost.

Solution:
Remove Guava from the shade plugin configuration. Guava remains as a transitive dependency, allowing applications to use the standard Guava library which has proper GraalVM native-image support.

Changes:

  • Remove com.google.guava:guava from shade plugin includes
  • Remove org.checkerframework:* from shade plugin includes
  • Remove com.google -> split.com.google relocation
  • Remove org.checkerframework -> split.org.checkerframework relocation
  • Update version to 4.18.2-graalvm to distinguish from upstream

Testing:

  • Built native image with Quarkus 3.27.1 + Mandrel JDK-23
  • Verified Split client works correctly at runtime
  • Tested feature flag resolution in native image

Reference: #614

This commit enables GraalVM native-image compilation for applications
using the Split.io Java SDK.

Problem:
The Split SDK shades Guava to split.com.google.common.* to avoid
dependency conflicts. However, this shaded Guava lacks the GraalVM
native-image configuration that standard Guava provides, causing
build failures with errors like:
  'Discovered unresolved type: split.com.google.common.util.concurrent.SettableFuture'

Root Cause:
Standard Guava (com.google.common.*) includes GraalVM native-image
configuration in META-INF/native-image/. When the SDK shades Guava
to split.com.google.common.*, this configuration is lost.

Solution:
Remove Guava from the shade plugin configuration. Guava remains as
a transitive dependency, allowing applications to use the standard
Guava library which has proper GraalVM native-image support.

Changes:
- Remove com.google.guava:guava from shade plugin includes
- Remove org.checkerframework:* from shade plugin includes
- Remove com.google -> split.com.google relocation
- Remove org.checkerframework -> split.org.checkerframework relocation
- Update version to 4.18.2-graalvm to distinguish from upstream

Testing:
- Built native image with Quarkus 3.27.1 + Mandrel JDK-23
- Verified Split client works correctly at runtime
- Tested feature flag resolution in native image

Reference: splitio#614
@alexcol23 alexcol23 requested a review from a team as a code owner January 14, 2026 19:16
@sanzmauro

Copy link
Copy Markdown
Contributor

@alexcol23 bringing this conversation over here as well
#614 (comment)

@nmayorsplit

Copy link
Copy Markdown
Contributor

Hi @alexcol23,
I've just released java-client with a non-shaded option. You can download the new version (4.18.3) and add a classifier option in your pom file, as shown in the example below:

<dependency>
            <groupId>io.split.client</groupId>
            <artifactId>java-client</artifactId>
            <version>4.18.3</version>
            <classifier>non-shaded</classifier>
  </dependency>

Please let me know if it works for you.
Thank you!

@nmayorsplit nmayorsplit closed this Mar 5, 2026
@wtorres02

Copy link
Copy Markdown

Hi @nmayorsplit @sanzmauro @alexcol23

The issue we encountered

Following up on the non-shaded release of 4.18.3 — we were able to migrate from our custom fork and wanted to share our findings in case they help other users or inform a future release.

After switching to java-client:4.18.3 with the non-shaded classifier, our GraalVM native image build failed with:

Discovered unresolved type during parsing: io.split.storages.pluggable.domain.UserStorageWrapper Caused by: java.lang.ClassNotFoundException: pluggable.CustomStorageWrapper

UserStorageWrapper (present in the non-shaded jar) implements pluggable.CustomStorageWrapper, but that interface is not bundled in the non-shaded jar and is not declared as a transitive Maven dependency either. GraalVM's static analysis resolves the full type hierarchy at build time, so the missing interface causes a hard compilation failure — even if the pluggable storage feature is never used at runtime.

How we fixed it

We added io.split.client:pluggable-storage as an explicit dependency alongside the non-shaded client. This resolves the GraalVM error and the native image builds successfully.

The concern

The latest available version of pluggable-storage on Maven Central is 4.13.0-rc3, which is a release candidate. Shipping an RC artifact as a runtime dependency in production is not ideal, and we'd like to understand the roadmap here.

Would it be possible to either:
  1. Publish a stable GA release of pluggable-storage, or
  2. Add pluggable-storage as an explicit true Maven dependency on the non-shaded jar so it resolves transitively without users needing to declare it manually?

Happy to provide more context or a reproducer if useful. Thanks for the quick turnaround on the non-shaded release!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants