什么是 Maven 中未使用/未声明的依赖关系?如何处理它们?

91

Maven dependency:analyze 指出我的项目中存在依赖问题。它是如何确定哪些是未使用的和未声明的? 我该如何处理这些问题?

示例:

$ 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

注意:许多这些依赖项在我的运行时容器中被使用,我将它们声明为“provided”,以避免在类路径上出现具有不同版本的相同库。


相关问题:https://dev59.com/a3fZa4cB1Zd3GeqPYf7t. - Sergey Vyacheslavovich Brunov
4个回答

109

不确定Maven是如何确定这些内容的。不需要解决此报告中报告的所有问题,但可以根据需要使用此信息。

未声明的依赖项是那些在您的项目中需要,但没有明确声明为依赖项的依赖项。但是,由于其他依赖项在您的项目中的传递依赖关系,它们是可用的。明确声明这些依赖项是个好主意。这也允许您控制这些依赖项的版本(可能与您的运行时提供的版本相匹配)。

至于未使用的声明依赖项,最好将其删除。为什么要向项目添加不必要的依赖项呢?但是,转换性仍然会带来这些依赖项,可能与您的运行时版本冲突。在这种情况下,您将需要指定它们,基本上是为了控制version

顺便说一下,mvn dependency:tree给出了项目的依赖树,这使您更好地了解每个依赖项在您的项目中的作用。


15
有些依赖关系看似未被使用,但其实是被使用了。例如,一些 JDBC 驱动程序或配置 JAR 包可能需要应用程序上下文。 - AHungerArtist
17
如果你分析依赖时不使用 ignoreNonCompile 标志,具有“runtime”或“provided”范围的依赖项会被标记为“未使用声明”。请注意,翻译过程中不改变原意。 - Duncan Jones
15
在使用Maven时,为什么要显式声明传递依赖关系呢?难道自动处理传递依赖不是Maven的一大优点吗? - slim
15
拉古拉姆在提到未声明的依赖关系。也就是说,你的项目 A 使用了库 B ,而库 B 又依赖于库 C。如果你也直接使用了库 C ,则不需要声明它——Maven 将通过传递性依赖自动引入它。但是,如果没有声明这个依赖关系,你就无法控制版本。例如,如果 B 决定升级到下一个版本的 C,除非更新是向后兼容的,否则你的项目 A 可能会出现问题。 - b7kich

17

关于:

"如何确定哪些是未使用的和哪些是未声明的?"

Maven使用Object WebASM框架来分析您的原始字节码。它遍历所有类,然后建立一个列出这些类引用的所有类的列表。这就是它的实现原理。

至于要做什么,我不建议删除“未使用的已声明依赖项”,除非您确信它们确实没有被使用。


谢谢!我遇到了一个虚假的“未使用声明依赖项”警告,针对一个库,尽管我正在导入和使用其中的类型,所以我无法弄清楚原因。但是如果Maven检查字节码而不是源代码,那就可以解释了:我使用的类型是一个具有仅源代码保留的注释类型,这意味着注释的使用从未进入字节码,所以Maven无法看到它。 - Aasmund Eldhuset

8
使用了未声明的依赖关系
简单来说,它们是传递依赖关系,您正在使用它们,但是在 POM 文件中没有显式地声明它们。
在下面的图示中,橙色是表示这种依赖。
enter image description here 提示:
最好在 POM 文件中 声明 它们,以松散耦合到你的一级依赖项,这样将来如果它们计划更改实现而不再使用此传递依赖关系,则您的应用程序将是安全的! 未使用的声明依赖关系
简单来说,它们是依赖关系,您在 POM 文件中声明它们,但在应用程序代码中 没有使用它们
在下面的图示中,红色表示这种依赖关系。
enter image description here 提示:
最好从 POM 文件中 删除 它们,因为它们没有使用,可以节省应用程序构件的最终大小,并避免任何开发人员因错误地使用错误的类而出错!

2
这个问题可以通过在pom.xml中添加ignoredUnusedDeclaredDependencies来轻松解决。
 <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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接