11

maven-dependency-plugin detects spring boot dependencies as unused, but they are actually requied to run my application. Would I have made something wrong ?

My pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <artifactId>my-service</artifactId>
    <packaging>jar</packaging>
    <name>my-service</name>
    <description>my service</description>

    <parent>
        <groupId>com.my</groupId>
        <artifactId>parent</artifactId>
        <version>0.2.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>javax.ws.rs</groupId>
                    <artifactId>jsr311-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <!--Analyze maven dependencies at verify phase-->
            <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.10</version>
                <executions>
                    <execution>
                        <id>analyze</id>
                        <goals>
                            <goal>analyze-only</goal>
                        </goals>
                        <configuration>
                            <ignoreNonCompile>true</ignoreNonCompile>
                            <failOnWarning>false</failOnWarning>
                            <outputXML>true</outputXML>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

My logs

[INFO] --- maven-dependency-plugin:2.10:analyze-only (analyze) @ resource-service ---
[WARNING] Unused declared dependencies found:
[WARNING]    org.springframework.boot:spring-boot-starter-actuator:jar:1.3.5.RELEASE:compile
[WARNING]    org.springframework.cloud:spring-cloud-starter-oauth2:jar:1.1.0.RELEASE:compile
[WARNING]    org.springframework.boot:spring-boot-configuration-processor:jar:1.3.5.RELEASE:compile
[WARNING]    org.springframework.cloud:spring-cloud-starter-eureka:jar:1.1.0.RELEASE:compile
[INFO] ------------------------------------------------------------------------
Pleymor
  • 2,611
  • 1
  • 32
  • 44

3 Answers3

6

This is normal since your code doesn't directly utilize any of those dependencies. The way Spring Boot works is it analyzes your classpath and will autoconfigure many different things for you simply by adding the corresponding dependency. Since the configuration is happening outside of your application code, Maven believes these dependencies to be unused.

Kyle Anderson
  • 6,801
  • 1
  • 29
  • 41
  • 3
    Ok, so finally `maven-dependency-plugin` `analyze-only` simply can't be used with spring boot projects ? Moreover, `spring-starters` are bundles of dependencies to keep pom.xml simple and consistent. It implies transitive dependencies seen as `should be declared` by `maven-dependency-plugin` which doesn't share the same best practices. – Pleymor May 31 '16 at 08:13
  • 1
    @Pleymor No, spring boot projects are not different from any other maven project. Static code analysis tools like `maven-dependency-plugin` can not detect runtime dependencies, so you should instruct them about runtime dependencies. [See my answer](https://stackoverflow.com/a/46631984/421162) – Kerem Baydoğan Nov 03 '17 at 08:42
6

If you want to mark these dependencies as used.

Edit your pom.xml as below

<plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.10</version>
    <executions>
        <execution>
            <id>analyze</id>
            <goals>
                <goal>analyze-only</goal>
            </goals>
            <configuration>
                <ignoreNonCompile>true</ignoreNonCompile>
                <failOnWarning>false</failOnWarning>
                <outputXML>true</outputXML>
                <usedDependencies>
                    <usedDependency>org.springframework.boot:spring-boot-starter-actuator</usedDependency>
                    <usedDependency>org.springframework.cloud:spring-cloud-starter-oauth2</usedDependency>
                    <usedDependency>org.springframework.boot:spring-boot-configuration-processor</usedDependency>
                    <usedDependency>org.springframework.cloud:spring-cloud-starter-eureka</usedDependency>
                </usedDependencies>
            </configuration>
        </execution>
    </executions>
</plugin>
Kerem Baydoğan
  • 10,475
  • 1
  • 43
  • 50
3

An enhancement for the @Kerem answer is to exclude all spring dependencies once (using regular expression) instead of listing them one by one which needs future attention to unused/used dependencies.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin.version}</version>
<executions>
    <execution>
        <id>analyze-dependencies</id>
        <goals>
            <goal>analyze-only</goal>
        </goals>
        <configuration>
            <failOnWarning>true</failOnWarning>

            <ignoredUnusedDeclaredDependencies>
                <!-- Because of SpringBoot auto-configurations, the configuration is happening outside of your application code, so Maven believes these dependencies to be unused -->
                <!-- Static code analysis tools like (maven-dependency-plugin) can not detect runtime dependencies, so you should instruct them about runtime dependencies -->
                <!-- https://stackoverflow.com/questions/37528928/spring-boot-core-dependencies-seen-as-unused-by-maven-dependency-plugin -->
                <ignoredUnusedDeclaredDependency>org.springframework*:*</ignoredUnusedDeclaredDependency>
            </ignoredUnusedDeclaredDependencies>

        </configuration>
    </execution>
</executions>
Ahmed Nabil
  • 17,392
  • 11
  • 61
  • 88