M. Justin created MDEP-557:
------------------------------
Summary: In dependency analysis, support Spring Boot style
intentional transitive compile-time dependencies
Key: MDEP-557
URL: https://issues.apache.org/jira/browse/MDEP-557
Project: Maven Dependency Plugin
Issue Type: New Feature
Components: analyze
Reporter: M. Justin
Priority: Minor
h1. Request
It would be useful if using Spring Boot "starter" dependencies as intended
didn't cause warnings with dependency:analyze (and related goals).
h1. Background
Spring Boot has a notion of "starter" dependencies. One of the primary
purposes of starter dependencies is to transitively bring in numerous other
dependencies to be used at both runtime and compile time. Per [Spring Boot's
documentation|http://docs.spring.io/spring-boot/docs/1.5.1.RELEASE/reference/htmlsingle/#using-boot-starter]:
{quote}
Starters are a set of convenient dependency descriptors that you can include in
your application. You get a one-stop-shop for all the Spring and related
technology that you need, without having to hunt through sample code and copy
paste loads of dependency descriptors. For example, if you want to get started
using Spring and JPA for database access, just include the
spring-boot-starter-data-jpa dependency in your project, and you are good to go.
The starters contain a lot of the dependencies that you need to get a project
up and running quickly and with a consistent, supported set of managed
transitive dependencies.
{quote}
However, this is at odds with the analysis done by
[dependency:analyze|https://maven.apache.org/plugins/maven-dependency-plugin/analyze-mojo.html]
(and similar goals in the dependency plugin). The analyze goals will warn
that the starter projects are "unused declared dependencies" and any
compile-time dependencies that are transitively brought in this way will
produce "used undeclared dependencies" warnings. Note that this warning
behavior is consistent with the [Maven dependency
documentation|http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope]
where it states that it is intended that all compile dependencies be
explicitly listed, rather than transitively used at compile time:
{quote}it is intended that \[transitive compile dependencies\] should be
runtime scope instead, so that all compile dependencies must be explicitly
listed - however, there is the case where the library you depend on extends a
class from another library, forcing you to have available at compile time. For
this reason, compile time dependencies remain as compile scope even when they
are transitive.{quote}
As a concrete example, here are the warnings generated by {{mvn
dependency:analyze}} on Spring Boot's own "[Getting
Started|https://spring.io/guides/gs/spring-boot/]" example:
{code}Used undeclared dependencies found:
org.springframework:spring-web:jar:4.3.6.RELEASE:compile
org.springframework.boot:spring-boot-test:jar:1.5.1.RELEASE:test
org.springframework.boot:spring-boot-test-autoconfigure:jar:1.5.1.RELEASE:test
org.springframework:spring-test:jar:4.3.6.RELEASE:test
org.springframework.boot:spring-boot:jar:1.5.1.RELEASE:compile
org.hamcrest:hamcrest-library:jar:1.3:test
org.springframework:spring-context:jar:4.3.6.RELEASE:compile
junit:junit:jar:4.12:test
org.springframework.boot:spring-boot-autoconfigure:jar:1.5.1.RELEASE:compile
org.springframework:spring-beans:jar:4.3.6.RELEASE:compile
Unused declared dependencies found:
org.springframework.boot:spring-boot-starter-web:jar:1.5.1.RELEASE:compile
org.springframework.boot:spring-boot-starter-test:jar:1.5.1.RELEASE:test
org.springframework.boot:spring-boot-starter-actuator:jar:1.5.1.RELEASE:compile{code}
My initial thought was that perhaps Spring Boot was misuing the Maven
dependency mechanism through their approach, however that is not their
interpretation (see the discussion at
[spring-boot#8341|https://github.com/spring-projects/spring-boot/issues/8341]).
So, assuming I'm interpreting things correctly, it seems like the thought is
that Spring Boot's usage of dependencies is A-OK. Given this, and the impact
of Spring Boot in the Java ecosystem, it seems like it would be good for there
to be support for this pattern within Maven's dependency analysis. I'm not
sure what the most appropriate mechanism for this would be, however (and
whether the dependency plugin is the primary place it should be supported). Is
this just something that should be configurable within the dependency:analyze
plugin itself? Are the starter dependencies a new class of dependency that
should be called out within Maven? Is this something where the starter
dependency should be able to declare that its compile-time dependencies are
meant to be exported and directly used?
h1. Workaround
The obvious workaround is to mark the starter dependencies as ignoreNonCompile,
and explicitly list all transitively used compile-time dependencies. However,
this gets rid of one of the primary stated benefits of using the starter
dependencies. It still provides the benefit of IDE auto-completion, at which
point the dependencies can be manually added to the POM as used.
The other option would be to not do anything, but then it's impossible to tell
the difference between used undeclared dependencies that are OK because they
are transitively provided, and those that are in the list because they are
inadvertantly depended on.
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)