Uploaded image for project: 'Maven Dependency Plugin'
  1. Maven Dependency Plugin
  2. MDEP-557

In dependency analysis, support Spring Boot style intentional transitive compile-time dependencies

    XMLWordPrintableJSON

    Details

    • Type: New Feature
    • Status: Open
    • Priority: Minor
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: analyze
    • Labels:

      Description

      Request

      It would be useful if using Spring Boot "starter" dependencies as intended didn't cause warnings with dependency:analyze (and related goals).

      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:

      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.

      However, this is at odds with the analysis done by dependency:analyze (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 where it states that it is intended that all compile dependencies be explicitly listed, rather than transitively used at compile time:

      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.

      As a concrete example, here are the warnings generated by mvn dependency:analyze on Spring Boot's own "Getting Started" example:

      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

      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).

      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?

      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.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                mjjustin M. Justin
              • Votes:
                3 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated: