90

Maven dependency:analyze complains about the dependencies in my project. How does it determine which are unused and which are undeclared? What should I do about them?

Example:

$ mvn dependency:analyze 
...
[WARNING] Used undeclared dependencies found:
[WARNING]    org.slf4j:slf4j-api:jar:1.5.0:provided
[WARNING]    commons-logging:commons-logging:jar:1.1.1:compile
[WARNING]    commons-dbutils:commons-dbutils:jar:1.1-osgi:provided
[WARNING]    org.codehaus.jackson:jackson-core-asl:jar:1.6.1:compile

...
[WARNING] Unused declared dependencies found:
[WARNING]    commons-cli:commons-cli:jar:1.0:compile
[WARNING]    org.mortbay.jetty:servlet-api:jar:2.5-20081211:test
[WARNING]    org.apache.httpcomponents:httpclient:jar:4.0-alpha4:compile
[WARNING]    commons-collections:commons-collections:jar:3.2:provided
[WARNING]    javax.mail:mail:jar:1.4:provided

Note: A lot of these dependencies are used in my runtime container and I declared them as provided to avoid having the same library on the classpath twice with different versions.

Ahmed Nabil
  • 17,392
  • 11
  • 61
  • 88
b7kich
  • 4,253
  • 3
  • 28
  • 29

4 Answers4

109

Not sure how Maven determines this. It is not required to address all the items reported by this, but this information can be used as appropriate.

Used undeclared dependencies are those which are required, but have not been explicitly declared as dependencies in your project. They are however available thanks to transitive dependency of other dependencies in your project. It is a good idea to explicitly declare these dependencies. This also allows you to control the version of these dependencies (perhaps matching the version provided by your runtime).

As for unused declared dependencies, it is a good idea to remove them. Why add unnecessary dependency to your project? But then transitivity can bring these in anyway, perhaps, conflicting with your runtime versions. In this case, you will need to specify them — essentially to control the version.

By the way, mvn dependency:tree gives the dependency tree of the project, which gives you a better perspective of how each dependency fits in in your project.

gvlasov
  • 18,638
  • 21
  • 74
  • 110
Raghuram
  • 51,854
  • 11
  • 110
  • 122
  • 15
    Also, dependencies can appear unused, but actually are. Some examples of this are jdbc drivers or config jars that have needed application contexts. – AHungerArtist Apr 19 '12 at 22:37
  • 17
    Dependencies with `runtime` or `provided` scope will flag up as "Unused declared" unless you use the `ignoreNonCompile` flag when analysing dependencies. – Duncan Jones Apr 02 '13 at 10:04
  • 15
    Why is it a good idea to explicitly declare transitive dependencies? Isn't automating transitive dependencies part of what Maven is good for? – slim Mar 16 '15 at 16:40
  • 15
    Raghuram was referring to used undeclared dependencies. I.e. your project A uses library B which depends on library C. If you also use C directly You don't have to declare it - maven will automatically pull it in through the transitive dependency. But without declaring the dependency you don't have any control over the version. E.g. if B decides to update to the next version of C your project A may break unless the update is backwards compatible – b7kich Apr 12 '16 at 22:19
17

The answer to:

"How does it determine which are unused and which are undeclared?".

Maven uses Object WebASM framework that analyzes your raw bytecode. It goes through all your classes and then builds a list of all classes that these reference. That is the how.

As to what to do, I would not recommend removing the "unused, declared dependecies" unless you are absolutely sure they actually unused.

Zwakele Mgabhi
  • 377
  • 2
  • 8
  • Thank you! I was experiencing a false "unused declared dependency" warning for a library, even though I was importing and using a type from it, so I couldn't figure out why. But if Maven inspects the bytecode rather than the source code, that explains it: the type I was using was an annotation type with source-only retention, meaning that the usage of the annotation never made it into the bytecode, so that's why Maven couldn't see it. – Aasmund Eldhuset Apr 21 '22 at 14:06
7

Used undeclared dependencies
Simply, they are the transitive dependencies which you are using them but WITHOUT declaring them explicitly inside your POM file.

In the below digram, the orange colored one.
enter image description here

Hint:
It is good idea to declare them inside your POM file to be loosly coupled against your first level dependencies, so in the future if they planned to change their implementation and not to use this transitive dependency anymore, your application will be safe!

Unused declared dependencies
Simply, they are the dependencies which you are declearing them inside your POM file WITHOUT using them in your application code.

In the below digram, the red colored one.
enter image description here

Hint:
It is good idea to remove them from your POM file, because they are not used and to save the final size of the application artifact also to avoid any developer from using wrong classes by mistake!

Ahmed Nabil
  • 17,392
  • 11
  • 61
  • 88
1

This can be easily fixed with by adding ignoredUnusedDeclaredDependencies in pom.xml

 <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <configuration>
                <ignoredUnusedDeclaredDependencies>
                    <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-api</ignoredUnusedDeclaredDependency>
                </ignoredUnusedDeclaredDependencies>
            </configuration>
        </execution>
    </executions>
 </plugin>
Shambhav
  • 813
  • 7
  • 20