Fix/uberjar shadow9 - #471
Merged
Merged
Conversation
Fixes #470. The Shadow 8.3.9 -> 9.6.1 upgrade changed two behaviours that the build was not updated for, producing broken `java-cfenv-all` artifacts in 3.5.2 and 4.0.1. Shadow 9 defaults `duplicatesStrategy` to EXCLUDE, and duplicates are dropped before transformers run. `java-cfenv-all` ships its own `META-INF/spring.factories`, so it won that race and every dependency's copy was discarded before `PropertiesFileTransformer` could merge them. The published jar therefore only registered `CloudProfileApplicationListener`, and both `CfDataSourceEnvironmentPostProcessor` and `CfEnvironmentPostProcessor` were missing, so `spring.datasource.url` was never derived from `VCAP_SERVICES`. Setting `duplicatesStrategy` to INCLUDE lets the transformer see and merge every copy. Shadow 9 also no longer treats empty name/version segments in the `dependency(String)` notation as wildcards, so `dependency('org.springframework.boot::')` matched nothing and Spring Boot and Spring Framework were bundled into the uber jar. On Spring Boot 3+ that causes a classloader identity conflict. Using the explicit `:.*:.*` form restores the intended exclusion. The resulting jar drops from 7.9M to 1.7M, contains no `org/springframework` classes, and its `spring.factories` matches the last good release (4.0.0) exactly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Shadow 9 breakage in #470 shipped in two releases while every unit test passed, because nothing inspected the packaged artifact. Add a `verifyUberJar` task, wired into `check`, that opens the uber jar and asserts what actually has to hold: - no bundled `org/springframework` classes - `com.cedarsoftware.io` relocated, with the shaded classes present - `spring.factories` contains the entries contributed by each module, including both EnvironmentPostProcessors - `spring.factories` does not re-register Spring Boot's own post-processors, which happens if the factories are merged while Spring Boot is still bundled Reverting either half of the fix fails the task, as does reverting both (the state that shipped in 3.5.2 and 4.0.1). Also pin `shadowJar` to run after `jar`. Both write the same archive name because `archiveClassifier` is empty, so which one survives on disk was left to task scheduling; Gradle flags this as an implicit dependency once another task reads the artifact. Note java-util (`com.cedarsoftware.util`) is deliberately not relocated, matching the last good releases, so the check is scoped to `com.cedarsoftware.io`.
kvmw
approved these changes
Sep 1, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Verify the uber jar contents as part of check
The Shadow 9 breakage in #470 shipped in two releases while every unit
test passed, because nothing inspected the packaged artifact. Add a
verifyUberJartask, wired intocheck, that opens the uber jar andasserts what actually has to hold:
org/springframeworkclassescom.cedarsoftware.iorelocated, with the shaded classes presentspring.factoriescontains the entries contributed by each module,including both EnvironmentPostProcessors
spring.factoriesdoes not re-register Spring Boot's ownpost-processors, which happens if the factories are merged while
Spring Boot is still bundled
Reverting either half of the fix fails the task, as does reverting both
(the state that shipped in 3.5.2 and 4.0.1).
Also pin
shadowJarto run afterjar. Both write the same archive namebecause
archiveClassifieris empty, so which one survives on disk wasleft to task scheduling; Gradle flags this as an implicit dependency once
another task reads the artifact.