Link dependents of shaded reactor modules to the shaded JAR instead of target/classes - #145
Merged
tgodzik merged 2 commits intoJun 23, 2026
Merged
Conversation
jozanek
marked this pull request as ready for review
June 13, 2026 17:29
tgodzik
approved these changes
Jun 23, 2026
tgodzik
left a comment
Contributor
There was a problem hiding this comment.
LGTM Don't know too much about the plugin, but it seems if the plugin is not present, nothing changes, so we should be to merge
tgodzik
force-pushed
the
fix/shade-relocation-classpath
branch
from
June 23, 2026 18:08
2b7fa57 to
7682937
Compare
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.
Link dependents of shaded reactor modules to the shaded JAR instead of
target/classesProblem
A reactor module built by
maven-shade-plugin(uber-jar / class relocation) keeps relocated classes only inside the shaded JAR, never intarget/classes. But the plugin linked that module's dependents totarget/classes, so they got an empty directory on their classpath and failed withcannot find symbol, cascading down the subtree (e.g. neo4j:lucene9-shaded→lucene-index→ the cypher Scala stack, ~16 modules).Fixes scalameta/metals#3024.
Root cause
The stale
target/classesreached dependents through two paths: the explicit reactor-dependency list (build.getOutputDirectory()) and Maven's resolved classpath elements. A third, subtler leak: a shaded module left as a Bloop project dependency contributes itsclassesDirto the effective classpath through the dependency graph.Fix (plugin-only; Bloop core / Metals just consume the emitted JSON)
shadegoal (not mere plugin presence), and locate the JAR honoringoutputFile/finalName/shadedArtifactAttached. The module's GAV is never resolved from a repository (could wire a stale binary).target/classesat both classpath entry points.classesDircan't leak back via the dependency graph; a consumedtest-jarname is preserved (shade replaces the main artifact, not the test-jar).Behavior when the shaded JAR doesn't exist yet
bloopInstallruns atgenerate-resources, while shade binds topackage. On a clean tree the shaded JAR legitimately may not exist yet. In that case the plugin warns loudly (naming the module, telling the user tomvn package) and falls back to the previoustarget/classesbehavior, rather than failing the export or wiring an unrelated binary.This keeps the plugin consistent with its existing architecture (cf. "Download only external dependencies in multi module Maven projects" — the plugin deliberately avoids invoking Maven tasks and resolving reactor artifacts to stay fast at an early lifecycle phase). Making the default export fully self-sufficient for shaded modules (triggering the shade goal during export) is a larger change best handled on the Metals/import side, and is intentionally out of scope here.
Known gaps (not blocking)
outputFile/shadedArtifactAttached/ shade-finalNamebranches and the shaded-module-with-consumed-test-jar path are correct by construction but not yet covered by dedicated fixtures (each needs its own packaged module).