delanym commented on issue #680: URL: https://github.com/apache/maven-shade-plugin/issues/680#issuecomment-6521455159
## Summary I went back through this with 3.6.0, 3.6.2, and current master (`3.7.0-SNAPSHOT`). I no longer think this is a bug in the plugin. The behaviour follows from what `artifactSet` actually selects, and I think the original report was based on a misunderstanding of that interaction. ## Original scenario A project shades a subset of its dependencies using `artifactSet`, with: - `createDependencyReducedPom=true` - `promoteTransitiveDependencies=true` - `keepDependenciesWithProvidedScope=true` A dependency that was pulled in transitively ended up in the dependency-reduced POM at its original scope (`compile`) rather than `provided`, even though it was expected to be treated as a shaded dependency. ## What the plugin actually does The two operations use the same selection: 1. `processArtifactSelectors()` adds an artifact to `artifactIds` only when `ArtifactSelector.isSelected(artifact)` is true. That is exactly the set of artifacts passed to the shader. 2. `createDependencyReducedPom(artifactIds)` then walks the resolved artifacts, and for every dependency whose ID is in that set it changes the scope to `provided` when `keepDependenciesWithProvidedScope=true`. So, under `promoteTransitiveDependencies=true`, an artifact that is actually bundled is marked `provided` by construction. An artifact that is not bundled keeps its original scope. The two sets cannot disagree because they are derived from the same `ArtifactSelector` over the same `project.getArtifacts()` snapshot. ## Why the transitive dependency was not `provided` `artifactSet` does not expand into "a set of trees". Each resolved artifact is tested individually against the include/exclude patterns. The plugin does not recursively shade the transitive dependencies of an included artifact. So if an artifact is reached transitively and is not itself matched by `artifactSet`, it is not shaded. Leaving it at `compile` in the reduced POM is then correct: `provided` means "supplied by the runtime environment" and is not transitive to consumers. Marking a dependency that was not bundled as `provided` would actually be wrong. To get a transitive dependency both shaded and listed as `provided`, it has to be selected: add it explicitly (or with a wildcard) to `artifactSet`. That is also the concrete fix that worked in the original project — the artifact was made a first-class module and added to the includes. ## The one case that can still look like this The only case I can construct where classes end up in the shaded JAR without the owning artifact being selected is a nested/uber JAR: a selected artifact already contains another artifact's classes. Shade has no metadata to attribute those embedded classes back to the unselected dependency, so that dependency will remain at its original scope. That is a limitation of working from artifact metadata, not an incorrect scope decision, and it cannot be fixed generically without inspecting and attributing JAR contents. ## Possible upstream improvements - Clarify the docs: `keepDependenciesWithProvidedScope` only applies to artifacts selected for shading, while `promoteTransitiveDependencies` promotes all resolved transitives at their existing scope. This is the real source of the confusion (see also MSHADE-141). - Add an integration test covering all three flags together with an `artifactSet` include/exclude, since only `dep-reduced-pom-use-base-version` exercises the flag today. - Optionally warn when a relocation pattern targets packages that no selected artifact provides, though that would be noisy because relocating references to excluded classes is intentional. Two related, genuine open issues in the same area are MSHADE-202 (`promoteTransitiveDependencies` strips exclusions) and MSHADE-465 (promotion depth) / PR #770. ## Proposed resolution I am happy for this to be closed as working-as-designed, or converted into a documentation/integration-test issue. If someone does have a minimal reproducer where an artifact is demonstrably bundled and still comes out `compile`, I would like to see it — in particular the exact `artifactSet` include/exclude patterns and whether the classes arrive via a nested JAR. Otherwise I do not think there is a code fix to make here. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
