17

The maven-dependency-plugin identifies what it believes to be unused dependencies when you compile by producing warnings at compile time.

[WARNING] Unused declared dependencies found:
[WARNING]    org.foo:bar-api:jar:1.7.5:compile

In some cases this message is a false positive and the dependency is required transitively.

Question: How can I identify in my pom.xml that this is the case?

A_Di-Matteo
  • 26,902
  • 7
  • 94
  • 128
vpiTriumph
  • 3,116
  • 2
  • 27
  • 39
  • Which IDE do you use? – mrbela Apr 12 '16 at 12:39
  • 3
    @mrbela this is IDE independent. It involves Maven which you could run from the terminal if that was your preference. – vpiTriumph Apr 12 '16 at 12:40
  • Have you tried running maven with `--quiet` parameter? It should only display errors while using it. – dambros Apr 12 '16 at 12:43
  • @vpiTriumph which goal and configuration of the maven dependency tree di your configure in your pom? can you share the concerned part of your pom.xml file? – A_Di-Matteo Apr 12 '16 at 12:47
  • 1
    @dambros the goal here is to mark dependencies that are actually being used as such (in the pom) so when new instances of this warning appear they can be heeded. If I used `--quiet` then I'd be suppressing the `warnings` en masse. – vpiTriumph Apr 12 '16 at 12:55

6 Answers6

21

You should configure in your pom the ignoredDependencies element:

List of dependencies that will be ignored. Any dependency on this list will be excluded from the "declared but unused" and the "used but undeclared" list. The filter syntax is:

[groupId]:[artifactId]:[type]:[version]

where each pattern segment is optional and supports full and partial * wildcards. An empty pattern segment is treated as an implicit wildcard. *

As also specified by the official Exclude dependencies from dependency analysis. A sample configuration would be:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.10</version>
            <executions>
                <execution>
                    <id>analyze-dep</id>
                    <goals>
                        <goal>analyze-only</goal>
                    </goals>
                    <configuration>
                        <ignoredDependencies>
                            <ignoredDependency>org.foo:bar-api:jar:1.7.5</ignoredDependency>
                        </ignoredDependencies>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
Community
  • 1
  • 1
A_Di-Matteo
  • 26,902
  • 7
  • 94
  • 128
  • I believe this was exactly what I was looking for. I had done this on a project in the past but could not dig up an example. This is surprisingly sparsely covered on SO. I'll try it out. – vpiTriumph Apr 12 '16 at 13:04
  • The answer is correct for suppressing the warnings. I just want to point out, however, that maven is pretty good and not producing false positives for the /compile/ scope, so either: A - that's not a transitive dependency and the scope should be /runtime/ (and you'll still need to suppress the warnings), or B - that's a transitive dependency. In that case, you can get rid of the warning by simply removing the dependency from you dependencies section (and perhaps add it to the dependencyManagement if you need a particular version). – cleberz Nov 21 '17 at 22:55
  • With version 3.1.1, I needed to exclude the `` elements and simply specify the ignored dependencies in a comma-separated series/list (without newlines!) directly inside of ``. – Christian Conti-Vock Oct 16 '18 at 21:11
  • I did not find it working for either 2.10 or 3.1.1. I had already a list of 'usedDependencies' and I had to add the new one as one child among that as mentioned here to get it working https://maven.apache.org/plugins/maven-dependency-plugin/analyze-mojo.html#usedDependencies – Raj Feb 19 '19 at 17:16
  • Note that analyze-only is intended to be used in the build lifecycle, thus it assumes that the test-compile phase has been executed. If you did not execute the test-compile phase before the analyze-only goal then you can also run into unused declared dependency warnings. You can resolve this by making sure the test--compile phase is executed before, or by using the analyze goal instead of the analyze-only goal. See: https://maven.apache.org/components/plugins/maven-dependency-plugin/analyze-only-mojo.html – Korthout Nov 17 '20 at 12:18
4

That was nearly what i was looking for, but i guess you specify that a little more like:

<execution>
  <goals>
     <goal>analyze-only</goal>
  </goals>
  <configuration>
  <failOnWarning>true</failOnWarning>
  <ignoredUnusedDeclaredDependencies>
      <ignoredUnusedDeclaredDependency>org.reflections:reflections:*</ignoredUnusedDeclaredDependency>
  </ignoredUnusedDeclaredDependencies>
  <ignoredUsedUndeclaredDependencies>
      <ignoredUsedUndeclaredDependency>junit:*:*</ignoredUsedUndeclaredDependency>
  </ignoredUsedUndeclaredDependencies>
  <ignoreNonCompile>false</ignoreNonCompile>
  <outputXML>true</outputXML>
  </configuration>
 </execution>

So this does nearly the same but is more specific on which kind of dependencies should be ignored

2

You can use mvn dependency:tree to evaluate your dependencies.

Reference: https://maven.apache.org/plugins/maven-dependency-plugin/examples/resolving-conflicts-using-the-dependency-tree.html

npn_or_pnp
  • 407
  • 4
  • 10
  • I'm familiar with `mvn dependency:tree` but as I noted, ultimately some dependencies it identifies as unused are not possible to eliminate. Static analysis is poor at picking up usages of a dependency via reflection for example. – vpiTriumph Apr 12 '16 at 12:53
1

try using provided scope

provided This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.

1

Since maven-dependency-plugin version 2.6 you can use usedDependencies tag to force dependencies as used.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <configuration>
        <usedDependencies>
            <dependency>groupId:artifactId</dependency>
        </usedDependencies>
    </configuration>
</plugin>
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Manuel Romeiro
  • 1,002
  • 12
  • 14
  • Actually solved my issue, as I had a dependency being used exclusively through java reflection, so I wanted to force it as 'used'. Thanks! – vithoriop Jul 24 '18 at 23:17
1

This message can occur when you are not using dependency in compile time but in runtime. You can do following:

<dependency>
   <groupId>org.foo</groupId>
   <artifactId>bar-api</artifactId>
   <version>1.7.5</version>
   <scope>runtime</scope>
</dependency>