Skip to content

[build] Shaded fat-JARs (fluss-client, fluss-flink, etc.) leak shaded module-info.class, breaking JPMS modular consumption#4045

Description

@Sekelenao

Search before asking

  • I searched in the issues and found nothing similar.

Fluss version

main (development)

Please describe the bug 馃悶

Problem Summary

All shaded uber-JARs produced by Fluss (e.g. fluss-client, fluss-flink-1.20, fluss-flink-1.19, fluss-server) currently embed META-INF/versions/9/module-info.class originating from shaded dependencies (such as commons-lang3:3.18.0 and fluss-shaded-jackson).

As a result, on Java 9+, the Java Platform Module System (JPMS) treats these shaded JARs as the named module org.apache.commons.lang3 rather than deriving an automatic module (e.g. fluss.client, fluss.flink).

How to Reproduce

Run jar --describe-module on any built shaded JAR (e.g., fluss-client or fluss-flink-1.20):

jar --describe-module --file=fluss-client-1.0-SNAPSHOT.jar --release 21

Actual Output:

releases: 9

org.apache.commons.lang3@3.18.0 jar:file:///.../fluss-client-1.0-SNAPSHOT.jar!/META-INF/versions/9/module-info.class
exports org.apache.commons.lang3
exports org.apache.commons.lang3.arch
...
requires java.base mandated
requires java.desktop

Notice that:

  1. The entire Fluss JAR is identified as module org.apache.commons.lang3.
  2. None of the org.apache.fluss.* packages are exported.

Impact on Downstream Projects

Downstream projects using the Java Module System (module-info.java) cannot access any Fluss APIs (org.apache.fluss.client.*, org.apache.fluss.flink.*, org.apache.fluss.config.*) without manually configuring awkward compiler flags such as:
--add-exports org.apache.commons.lang3/org.apache.fluss.client=<target-module>

Solution

Solution Details

In the root pom.xml, configure the global maven-shade-plugin filter (<artifact>*</artifact>) to exclude all module-info.class and multi-release module-info.class files:

<filter>
    <artifact>*</artifact>
    <excludes>
        ...
        <!-- Do not copy module-info.class from shaded dependencies -->
        <exclude>module-info.class</exclude>
        <exclude>META-INF/versions/**/module-info.class</exclude>
        ...
    </excludes>
</filter>

This is the standard pattern used across Apache projects (Flink, Spark) when bundling shaded dependencies into uber-JARs.

Local Validation

I have tested this fix across multiple modules:

  • fluss-client now correctly derives fluss.client@1.0-SNAPSHOT automatic with all packages exported.
  • fluss-flink-1.20 correctly derives fluss.flink@1.20-1.0-SNAPSHOT automatic.
  • fluss-server correctly derives fluss.server@1.0-SNAPSHOT automatic.
  • Spotless formatting (mvn spotless:check) and Checkstyle pass cleanly.

I have this fix ready and tested locally, and would be very happy to submit a Pull Request if the maintainers approve this approach.

Are you willing to submit a PR?

  • I'm willing to submit a PR!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions