为什么解析的依赖关系在 Java 8 和 Java 11 之间不同?
Why does resolved dependencies differ between Java 8 and Java 11?
给定一个非常简单的 Maven 项目,其中包含一个包含单个依赖项的 pom 文件:
<?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>org.example</groupId>
<artifactId>maven-test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>cxf-xjc-runtime</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
</project>
当 运行 mvn dependency:tree
根据 Java 版本给出不同的结果。
与Java8:
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< org.example:maven-test >-----------------------
[INFO] Building maven-test 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ maven-test ---
[INFO] org.example:maven-test:jar:1.0-SNAPSHOT
[INFO] \- org.apache.cxf.xjc-utils:cxf-xjc-runtime:jar:3.3.0:compile
[INFO] \- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.2:compile
[INFO] \- jakarta.activation:jakarta.activation-api:jar:1.2.1:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.982 s
[INFO] Finished at: 2020-06-22T15:05:56+02:00
[INFO] ------------------------------------------------------------------------
与Java11:
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< org.example:maven-test >-----------------------
[INFO] Building maven-test 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ maven-test ---
[INFO] org.example:maven-test:jar:1.0-SNAPSHOT
[INFO] \- org.apache.cxf.xjc-utils:cxf-xjc-runtime:jar:3.3.0:compile
[INFO] +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.2:compile
[INFO] | \- jakarta.activation:jakarta.activation-api:jar:1.2.1:compile
[INFO] +- javax.annotation:javax.annotation-api:jar:1.3.1:compile <-- This and below only with Java 11
[INFO] +- javax.xml.ws:jaxws-api:jar:2.3.0:compile
[INFO] | +- javax.xml.bind:jaxb-api:jar:2.3.0:compile
[INFO] | \- javax.xml.soap:javax.xml.soap-api:jar:1.4.0:compile
[INFO] \- javax.activation:activation:jar:1.1.1:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.261 s
[INFO] Finished at: 2020-06-22T15:05:51+02:00
[INFO] ------------------------------------------------------------------------
我原以为这两个 Java 版本的树是一样的。
Maven 版本为 3.6.0.
为什么 Java 版本之间解析的依赖关系不同?
如果依赖关系已经存在于树的较高层,则依赖树 mojo 会修剪较低级别的依赖关系。
我们可以使用详细标志 (-Dverbose
) 来显示排除的依赖项。
查找特定工件:mvn dependency:tree -Dverbose -Dincludes=[groupId]:[artifactId]:[type]:[version]
请访问Maven Dependency Tree了解更多。
Java版本依赖树不同的原因在依赖中找到:
<dependency>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>cxf-xjc-runtime</artifactId>
<version>3.3.0</version>
</dependency>
这又将 xjc-utils
作为其父级:
<parent>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>xjc-utils</artifactId>
<version>3.3.0</version>
</parent>
在这个 POM 文件中,我们找到了使用 Java 8:
构建时排除的依赖项
<profile>
<id>java9-plus</id>
<activation>
<jdk>[9,)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
</profile>
这本身就很重要,只有在使用 Java 9 或更高版本时才会包含依赖项,如以下范围所述:<jdk>[9,)</jdk>
。标记的文档说明:
Specifies that this profile will be activated when a matching JDK is detected. For example, 1.4
only activates on JDKs versioned 1.4, while !1.4
matches any JDK that is not version 1.4.
此激活配置文件确保在使用 Java 11 时包含这些依赖项:
[INFO] +- javax.annotation:javax.annotation-api:jar:1.3.1:compile
[INFO] +- javax.xml.ws:jaxws-api:jar:2.3.0:compile
[INFO] | +- javax.xml.bind:jaxb-api:jar:2.3.0:compile
[INFO] | \- javax.xml.soap:javax.xml.soap-api:jar:1.4.0:compile
[INFO] \- javax.activation:activation:jar:1.1.1:compile
有关激活的更多信息,请参阅 official Maven documentation:
Activations are the key of a profile. The power of a profile comes from its ability to modify the basic POM only under certain circumstances. Those circumstances are specified via an activation
element.
连同另一个基于Java版本的激活示例:
<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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<profiles>
<profile>
<id>test</id>
<activation>
<activeByDefault>false</activeByDefault>
<jdk>1.5</jdk>
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
<property>
<name>sparrow-type</name>
<value>African</value>
</property>
<file>
<exists>${basedir}/file2.properties</exists>
<missing>${basedir}/file1.properties</missing>
</file>
</activation>
...
</profile>
</profiles>
</project>
给定一个非常简单的 Maven 项目,其中包含一个包含单个依赖项的 pom 文件:
<?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>org.example</groupId>
<artifactId>maven-test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>cxf-xjc-runtime</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
</project>
当 运行 mvn dependency:tree
根据 Java 版本给出不同的结果。
与Java8:
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< org.example:maven-test >-----------------------
[INFO] Building maven-test 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ maven-test ---
[INFO] org.example:maven-test:jar:1.0-SNAPSHOT
[INFO] \- org.apache.cxf.xjc-utils:cxf-xjc-runtime:jar:3.3.0:compile
[INFO] \- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.2:compile
[INFO] \- jakarta.activation:jakarta.activation-api:jar:1.2.1:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.982 s
[INFO] Finished at: 2020-06-22T15:05:56+02:00
[INFO] ------------------------------------------------------------------------
与Java11:
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< org.example:maven-test >-----------------------
[INFO] Building maven-test 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ maven-test ---
[INFO] org.example:maven-test:jar:1.0-SNAPSHOT
[INFO] \- org.apache.cxf.xjc-utils:cxf-xjc-runtime:jar:3.3.0:compile
[INFO] +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.2:compile
[INFO] | \- jakarta.activation:jakarta.activation-api:jar:1.2.1:compile
[INFO] +- javax.annotation:javax.annotation-api:jar:1.3.1:compile <-- This and below only with Java 11
[INFO] +- javax.xml.ws:jaxws-api:jar:2.3.0:compile
[INFO] | +- javax.xml.bind:jaxb-api:jar:2.3.0:compile
[INFO] | \- javax.xml.soap:javax.xml.soap-api:jar:1.4.0:compile
[INFO] \- javax.activation:activation:jar:1.1.1:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.261 s
[INFO] Finished at: 2020-06-22T15:05:51+02:00
[INFO] ------------------------------------------------------------------------
我原以为这两个 Java 版本的树是一样的。
Maven 版本为 3.6.0.
为什么 Java 版本之间解析的依赖关系不同?
如果依赖关系已经存在于树的较高层,则依赖树 mojo 会修剪较低级别的依赖关系。
我们可以使用详细标志 (-Dverbose
) 来显示排除的依赖项。
查找特定工件:mvn dependency:tree -Dverbose -Dincludes=[groupId]:[artifactId]:[type]:[version]
请访问Maven Dependency Tree了解更多。
Java版本依赖树不同的原因在依赖中找到:
<dependency>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>cxf-xjc-runtime</artifactId>
<version>3.3.0</version>
</dependency>
这又将 xjc-utils
作为其父级:
<parent>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>xjc-utils</artifactId>
<version>3.3.0</version>
</parent>
在这个 POM 文件中,我们找到了使用 Java 8:
构建时排除的依赖项<profile>
<id>java9-plus</id>
<activation>
<jdk>[9,)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
</profile>
这本身就很重要,只有在使用 Java 9 或更高版本时才会包含依赖项,如以下范围所述:<jdk>[9,)</jdk>
。标记的文档说明:
Specifies that this profile will be activated when a matching JDK is detected. For example,
1.4
only activates on JDKs versioned 1.4, while!1.4
matches any JDK that is not version 1.4.
此激活配置文件确保在使用 Java 11 时包含这些依赖项:
[INFO] +- javax.annotation:javax.annotation-api:jar:1.3.1:compile
[INFO] +- javax.xml.ws:jaxws-api:jar:2.3.0:compile
[INFO] | +- javax.xml.bind:jaxb-api:jar:2.3.0:compile
[INFO] | \- javax.xml.soap:javax.xml.soap-api:jar:1.4.0:compile
[INFO] \- javax.activation:activation:jar:1.1.1:compile
有关激活的更多信息,请参阅 official Maven documentation:
Activations are the key of a profile. The power of a profile comes from its ability to modify the basic POM only under certain circumstances. Those circumstances are specified via an
activation
element.
连同另一个基于Java版本的激活示例:
<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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<profiles>
<profile>
<id>test</id>
<activation>
<activeByDefault>false</activeByDefault>
<jdk>1.5</jdk>
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
<property>
<name>sparrow-type</name>
<value>African</value>
</property>
<file>
<exists>${basedir}/file2.properties</exists>
<missing>${basedir}/file1.properties</missing>
</file>
</activation>
...
</profile>
</profiles>
</project>