Freewind @ Thoughtworks scala java javascript dart 工具 编程实践 月结 math python english [comments admin] [feed]

(2015-05-04) 怎么显示一个maven项目中的第三方依赖

广告: 云梯:翻墙vpn (省10元) 土行孙:科研用户翻墙http proxy (有优惠)

Maven内置了maven-dependency-plugin:2.8(对于 maven 3.2.5来说),提供了如dependency:tree, dependency:list等命令,可以让我们显示所有项目的第三方依赖

插件地址

  1. 如何配置maven的插件:http://maven.apache.org/guides/mini/guide-configuring-plugins.html
  2. dependency-plugin: http://maven.apache.org/plugins/maven-dependency-plugin/usage.html

基本POM

下面是一个用于演示的基本pom.xml,可以把它保存在某个目录下的pom.xml中,再运行mvn dependency:tree即可。

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

    <groupId>in.freewind</groupId>
    <artifactId>maven-dependency-insight</artifactId>
    <version>0.1.1</version>
    <packaging>pom</packaging>

    <name>maven-dependency-insight</name>

    <properties>
        <maven-dependency-plugin.version>2.10</maven-dependency-plugin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>1.1.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</build>
</project>

这里精心选择了几个库,其中org.springframework.boot:spring-boot-starter-web:jar:1.1.5.RELEASE依赖于org.slf4j:slf4j-api:jar:1.7.7,但我这里又显式声明了org.slf4j:slf4j-api:1.7.1,目的是为了展示maven是如何处理版本冲突的。

另外前两个依赖没有指定scope,则默认为compile,第三个声明为test

mvn clean install

为保险起见,最好先mvn clean install一下。这样做是因为如果这个项目中有子项目,而且项目之间有未发布到仓库的SNAPSHOT的引用,不先把它们install到本地,执行其它的命令有可能报找不到依赖的错误。

执行完以后,会把项目发布到本地~/.m2目录下的合适位置,方便后来的查看

mvn dependency:resolve

运行这个命令,maven将会下载所需依赖并解决版本冲突。完成后会列出最终所用的依赖的版本,内容跟后面介绍的dependency:list相似。

不过我们通常还是用后面介绍的dependency:tree或者dependency:list来查看依赖

mvn dependency:tree

将以树形结构打印出所有依赖,如下:

[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-dependency-insight 0.1.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ maven-dependency-insight ---
[INFO] in.freewind:maven-dependency-insight:pom:0.1.1
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.1.5.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:1.1.5.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:1.1.5.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:1.1.5.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.1.5.RELEASE:compile
[INFO] |  |  |  +- org.slf4j:jcl-over-slf4j:jar:1.7.7:compile
[INFO] |  |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.7:compile
[INFO] |  |  |  +- org.slf4j:log4j-over-slf4j:jar:1.7.7:compile
[INFO] |  |  |  \- ch.qos.logback:logback-classic:jar:1.1.2:compile
[INFO] |  |  |     \- ch.qos.logback:logback-core:jar:1.1.2:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.13:runtime
[INFO] |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:1.1.5.RELEASE:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:7.0.54:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:7.0.54:compile
[INFO] |  |  \- org.apache.tomcat.embed:tomcat-embed-logging-juli:jar:7.0.54:compile
[INFO] |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.3.3:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.3.0:compile
[INFO] |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.3.3:compile
[INFO] |  +- org.hibernate:hibernate-validator:jar:5.0.3.Final:compile
[INFO] |  |  +- javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.1.1.GA:compile
[INFO] |  |  \- com.fasterxml:classmate:jar:1.0.0:compile
[INFO] |  +- org.springframework:spring-core:jar:4.0.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-web:jar:4.0.6.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-aop:jar:4.0.6.RELEASE:compile
[INFO] |  |  |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  |  +- org.springframework:spring-beans:jar:4.0.6.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-context:jar:4.0.6.RELEASE:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:4.0.6.RELEASE:compile
[INFO] |     \- org.springframework:spring-expression:jar:4.0.6.RELEASE:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.7.1:compile
[INFO] \- junit:junit:jar:4.11:test
[INFO]    \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.270 s
[INFO] Finished at: 2015-05-04T18:07:48+08:00
[INFO] Final Memory: 14M/309M
[INFO] ------------------------------------------------------------------------

可以看到,它将以树型结构显示我们声明的依赖,以及依赖自己的依赖。

org.slf4j:slf4j-api:jar:1.7.1:compile

对应了

groupId:artifactId:type:version:scope

注意这里只显示解决了版本冲突之后确定的版本,而不像gradle dependencies那样还会打印出重复的或者被跳过的版本。

例如搜索slf4j-api:jar只能搜到一个,版本冲突中失败的那个没有显示。

nearest definition

maven对于依赖的版本冲突,采用的是nearst definition,即从树的最上层向下,如果遇到有冲突的版本(即名字相同但版号本不同),则采用上层指定的版本。

比如这里我们自己声明的org.slf4j:slf4j-api:jar:1.7.1处于第一层,org.springframework.boot:spring-boot-starter-web:jar:1.1.5.RELEASE依赖的org.slf4j:slf4j-api:jar:1.7.7,虽然版本号较高,但由于层数较低,将被抛弃。

这种解决版本冲突的做法跟gradle不一样,gradle默认采用版本号较大的那个,而不管它们处于哪一层。

mvn dependency:list

有时候我们只关心有哪些依赖,而不关心它们的依赖关系,可以使用dependency:tree这个命令,显示的结果更容易读一些:

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-dependency-insight 0.1.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.10:list (default-cli) @ maven-dependency-insight ---
[INFO]
[INFO] The following files have been resolved:
[INFO]    com.fasterxml.jackson.core:jackson-databind:jar:2.3.3:compile
[INFO]    org.springframework.boot:spring-boot-starter-tomcat:jar:1.1.5.RELEASE:compile
[INFO]    com.fasterxml:classmate:jar:1.0.0:compile
[INFO]    org.slf4j:log4j-over-slf4j:jar:1.7.7:compile
[INFO]    aopalliance:aopalliance:jar:1.0:compile
[INFO]    org.springframework:spring-web:jar:4.0.6.RELEASE:compile
[INFO]    org.springframework:spring-aop:jar:4.0.6.RELEASE:compile
[INFO]    com.fasterxml.jackson.core:jackson-annotations:jar:2.3.0:compile
[INFO]    junit:junit:jar:4.11:test
[INFO]    org.apache.tomcat.embed:tomcat-embed-logging-juli:jar:7.0.54:compile
[INFO]    org.springframework:spring-context:jar:4.0.6.RELEASE:compile
[INFO]    org.slf4j:slf4j-api:jar:1.7.1:compile
[INFO]    org.springframework.boot:spring-boot-starter-logging:jar:1.1.5.RELEASE:compile
[INFO]    ch.qos.logback:logback-core:jar:1.1.2:compile
[INFO]    org.springframework:spring-webmvc:jar:4.0.6.RELEASE:compile
[INFO]    org.apache.tomcat.embed:tomcat-embed-core:jar:7.0.54:compile
[INFO]    org.springframework:spring-beans:jar:4.0.6.RELEASE:compile
[INFO]    org.apache.tomcat.embed:tomcat-embed-el:jar:7.0.54:compile
[INFO]    com.fasterxml.jackson.core:jackson-core:jar:2.3.3:compile
[INFO]    org.hamcrest:hamcrest-core:jar:1.3:test
[INFO]    org.hibernate:hibernate-validator:jar:5.0.3.Final:compile
[INFO]    org.springframework.boot:spring-boot-starter-web:jar:1.1.5.RELEASE:compile
[INFO]    org.slf4j:jcl-over-slf4j:jar:1.7.7:compile
[INFO]    org.jboss.logging:jboss-logging:jar:3.1.1.GA:compile
[INFO]    org.slf4j:jul-to-slf4j:jar:1.7.7:compile
[INFO]    org.springframework.boot:spring-boot-starter:jar:1.1.5.RELEASE:compile
[INFO]    org.yaml:snakeyaml:jar:1.13:runtime
[INFO]    org.springframework.boot:spring-boot:jar:1.1.5.RELEASE:compile
[INFO]    org.springframework.boot:spring-boot-autoconfigure:jar:1.1.5.RELEASE:compile
[INFO]    ch.qos.logback:logback-classic:jar:1.1.2:compile
[INFO]    javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO]    org.springframework:spring-core:jar:4.0.6.RELEASE:compile
[INFO]    org.springframework:spring-expression:jar:4.0.6.RELEASE:compile
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.381 s
[INFO] Finished at: 2015-05-04T19:36:47+08:00
[INFO] Final Memory: 14M/309M
[INFO] ------------------------------------------------------------------------

我们可以根据需求使用不同的命令。

mvn dependency:tree -Dverbose

有时候我们希望它能像gradle那样,把版本冲突中被抛弃的、以及重复的都显示出来,以便追踪,这时可以加上verbose参数:mvn dependency:tree -Dverbose

结果如下:

[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-dependency-insight 0.1.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ maven-dependency-insight ---
[WARNING] Using Maven 2 dependency tree to get verbose output, which may be inconsistent with actual Maven 3 resolution
[INFO] in.freewind:maven-dependency-insight:pom:0.1.1
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.1.5.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:1.1.5.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:1.1.5.RELEASE:compile
[INFO] |  |  |  +- (org.springframework:spring-core:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |  |  |  \- (org.springframework:spring-context:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:1.1.5.RELEASE:compile
[INFO] |  |  |  \- (org.springframework.boot:spring-boot:jar:1.1.5.RELEASE:compile - omitted for duplicate)
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.1.5.RELEASE:compile
[INFO] |  |  |  +- org.slf4j:jcl-over-slf4j:jar:1.7.7:compile
[INFO] |  |  |  |  \- (org.slf4j:slf4j-api:jar:1.7.7:compile - omitted for conflict with 1.7.1)
[INFO] |  |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.7:compile
[INFO] |  |  |  |  \- (org.slf4j:slf4j-api:jar:1.7.7:compile - omitted for duplicate)
[INFO] |  |  |  +- org.slf4j:log4j-over-slf4j:jar:1.7.7:compile
[INFO] |  |  |  |  \- (org.slf4j:slf4j-api:jar:1.7.7:compile - omitted for duplicate)
[INFO] |  |  |  \- ch.qos.logback:logback-classic:jar:1.1.2:compile
[INFO] |  |  |     +- ch.qos.logback:logback-core:jar:1.1.2:compile
[INFO] |  |  |     \- (org.slf4j:slf4j-api:jar:1.7.6:compile - omitted for conflict with 1.7.7)
[INFO] |  |  +- (org.springframework:spring-core:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.13:runtime
[INFO] |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:1.1.5.RELEASE:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:7.0.54:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:7.0.54:compile
[INFO] |  |  \- org.apache.tomcat.embed:tomcat-embed-logging-juli:jar:7.0.54:compile
[INFO] |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.3.3:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.3.0:compile
[INFO] |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.3.3:compile
[INFO] |  +- org.hibernate:hibernate-validator:jar:5.0.3.Final:compile
[INFO] |  |  +- javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.1.1.GA:compile
[INFO] |  |  \- com.fasterxml:classmate:jar:1.0.0:compile
[INFO] |  +- org.springframework:spring-core:jar:4.0.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-web:jar:4.0.6.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-aop:jar:4.0.6.RELEASE:compile
[INFO] |  |  |  +- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  |  |  +- (org.springframework:spring-beans:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |  |  |  \- (org.springframework:spring-core:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |  |  +- org.springframework:spring-beans:jar:4.0.6.RELEASE:compile
[INFO] |  |  |  \- (org.springframework:spring-core:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |  |  +- org.springframework:spring-context:jar:4.0.6.RELEASE:compile
[INFO] |  |  |  +- (org.springframework:spring-aop:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |  |  |  +- (org.springframework:spring-beans:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |  |  |  +- (org.springframework:spring-core:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |  |  |  \- (org.springframework:spring-expression:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |  |  \- (org.springframework:spring-core:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |  \- org.springframework:spring-webmvc:jar:4.0.6.RELEASE:compile
[INFO] |     +- (org.springframework:spring-beans:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |     +- (org.springframework:spring-context:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |     +- (org.springframework:spring-core:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |     +- org.springframework:spring-expression:jar:4.0.6.RELEASE:compile
[INFO] |     |  \- (org.springframework:spring-core:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] |     \- (org.springframework:spring-web:jar:4.0.6.RELEASE:compile - omitted for duplicate)
[INFO] +- org.slf4j:slf4j-api:jar:1.7.1:compile
[INFO] \- junit:junit:jar:4.11:test
[INFO]    \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.750 s
[INFO] Finished at: 2015-05-04T19:37:32+08:00
[INFO] Final Memory: 15M/437M
[INFO] ------------------------------------------------------------------------

可以看到结果多了一些东西:

(org.slf4j:slf4j-api:jar:1.7.7:compile - omitted for conflict with 1.7.1)

表示虽然声明的依赖是1.7.7,但由于maven决定采用1.7.1,所以这里将被忽略

(org.springframework:spring-web:jar:4.0.6.RELEASE:compile - omitted for duplicate)

该声明在前面已经出现过,这里将被忽略

如何把输出保存到文件

加上outputFile参数即可,比如mvn dependency:list -DoutputFile=/myfile.txt,将会把干净的输出写入过去。

如果包含多个模块

如果该项目有多个模块,运行该mvn dependency:tree将会显示所有模块的依赖,这跟gradle dependencies不一样,后者只显示当前依赖。

如何不下载SNAPSHOT包,加快显示

如果项目中引用了某个SNAPSHOT包,当我们执行上面的命令时,它会尝试重新下载,可能会比较慢。这时我们可以加上-o或者--offline参数,禁止下载。

mvn -o dependency:tree

如何使用2.10版的dependency-plugin

pom.xml中显式声明,则可以覆盖默认版本。

pom.xml中添加以下内容即可:

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <version>2.10</version>
    </plugin>
  </plugins>
</build>

把声明的依赖拷贝出来

运行mvn dependency:copy-dependencies,将会把所有采用的依赖(包括依赖的依赖),拷贝到target/dependency目录下。

如果加上-Dclassifier=sources,则会尝试下载并拷贝源代码包。

如果加上-DoutputDirectory=/mypath,则把拷贝到指定的目录/mypath

comments powered by Disqus