Skip to content

Fix/uberjar shadow9 3.x - #473

Merged
pivotal-david-osullivan merged 2 commits into
3.xfrom
fix/uberjar-shadow9-3.x
Sep 2, 2026
Merged

Fix/uberjar shadow9 3.x#473
pivotal-david-osullivan merged 2 commits into
3.xfrom
fix/uberjar-shadow9-3.x

Conversation

@pivotal-david-osullivan

Copy link
Copy Markdown
Member

Backport of #471

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 kvmw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pivotal-david-osullivan
pivotal-david-osullivan merged commit 22c4139 into 3.x Sep 2, 2026
2 checks passed
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.

2 participants