Proposal: Avoid publishing fat/uber/shaded JARs for library artifacts
Summary
This project currently publishes a fat/uber/shaded JAR that bundles its dependencies. While this approach can be convenient for standalone applications, it introduces several problems for libraries intended to be consumed by other projects.
I propose that the project publish thin JARs (standard library artifacts without bundled dependencies) and rely on normal dependency management through Gradle instead.
If a bundled application artifact is needed, the installDist task can be used to create a Zip file containing all artifacts as well as scripts for starting the application.
If a bundled library artifact is needed for specific use cases, it could optionally be published as a classifier (e.g. -all or -shaded) rather than being the primary artifact.
Why fat JARs are problematic for libraries
1. Breaks dependency management
When dependencies are bundled inside the artifact:
- Consumers cannot manage dependency versions through their build system
- BOM alignment and dependency resolution become ineffective
- Projects cannot easily upgrade vulnerable dependencies
This undermines the core benefit of modern dependency management systems.
2. Increased risk of dependency conflicts
Bundled dependencies increase the likelihood of classpath conflicts when consumers use other libraries that depend on the same components.
Typical issues include:
- Duplicate classes
- Different library versions on the classpath
- Hard-to-diagnose runtime errors
Thin artifacts allow the build tool to resolve a consistent dependency graph.
3. Security and compliance concerns
Embedding third-party code inside the JAR complicates:
- vulnerability scanning
- license attribution
- SBOM generation
- dependency auditing
With thin artifacts, tools can accurately detect dependency versions and vulnerabilities.
4. Resource and metadata collisions
Shading or merging dependencies can break or corrupt metadata such as:
META-INF/services/* (ServiceLoader)
META-INF/spring.*
module-info.class
- signatures in
META-INF
- logging configurations
These issues can cause subtle runtime failures.
5. Problems with Java modules and other runtimes
Fat JARs frequently create issues with:
- JPMS (Java Platform Module System)
- split packages
- multi-release JARs
- OSGi environments
- Android builds
Publishing standard library artifacts avoids these compatibility problems.
6. Larger artifacts and slower builds
Bundled artifacts are significantly larger and require additional build-time transformations, which can slow down:
- CI pipelines
- dependency downloads
- repository storage
Recommended approach
Publish standard thin library artifacts and rely on dependency management.
If a bundled artifact is still desirable for certain use cases (e.g. command-line usage), it can be published as an optional classifier:
Proposal: Avoid publishing fat/uber/shaded JARs for library artifacts
Summary
This project currently publishes a fat/uber/shaded JAR that bundles its dependencies. While this approach can be convenient for standalone applications, it introduces several problems for libraries intended to be consumed by other projects.
I propose that the project publish thin JARs (standard library artifacts without bundled dependencies) and rely on normal dependency management through Gradle instead.
If a bundled application artifact is needed, the
installDisttask can be used to create a Zip file containing all artifacts as well as scripts for starting the application.If a bundled library artifact is needed for specific use cases, it could optionally be published as a classifier (e.g.
-allor-shaded) rather than being the primary artifact.Why fat JARs are problematic for libraries
1. Breaks dependency management
When dependencies are bundled inside the artifact:
This undermines the core benefit of modern dependency management systems.
2. Increased risk of dependency conflicts
Bundled dependencies increase the likelihood of classpath conflicts when consumers use other libraries that depend on the same components.
Typical issues include:
Thin artifacts allow the build tool to resolve a consistent dependency graph.
3. Security and compliance concerns
Embedding third-party code inside the JAR complicates:
With thin artifacts, tools can accurately detect dependency versions and vulnerabilities.
4. Resource and metadata collisions
Shading or merging dependencies can break or corrupt metadata such as:
META-INF/services/*(ServiceLoader)META-INF/spring.*module-info.classMETA-INFThese issues can cause subtle runtime failures.
5. Problems with Java modules and other runtimes
Fat JARs frequently create issues with:
Publishing standard library artifacts avoids these compatibility problems.
6. Larger artifacts and slower builds
Bundled artifacts are significantly larger and require additional build-time transformations, which can slow down:
Recommended approach
Publish standard thin library artifacts and rely on dependency management.
If a bundled artifact is still desirable for certain use cases (e.g. command-line usage), it can be published as an optional classifier: