项目b:
<project> <modelversion>4.0.0</modelversion> <groupid>maven</groupid> <artifactid>b</artifactid> <packaging>pom</packaging> <name>b</name> <version>1.0</version> <dependencymanagement> <dependencies> <dependency> <artifactid>a</artifactid> <type>pom</type> <scope>import</scope> </dependency> <groupid>test</groupid> <artifactid>d</artifactid> </dependencies> </dependencymanagement> <scope>runtime</scope> <artifactid>c</artifactid> </project>
假设a就是上一个例子中定义的pom,那么最终的结果也是一致的。除了在b中定义的d模块,所有a的管理依赖都会导入到b中。
项目x:
<artifactid>x</artifactid> <name>x</name> <version>1.1</version> <scope>compile</scope>
项目y:
<artifactid>y</artifactid> <name>y</name> <version>1.2</version>
项目z:
<artifactid>z</artifactid> <name>z</name>
在上面的例子中,z导入了x和y的管理依赖。不过有个问题,x和y都包含了依赖a。在这里,会使用1.1版本的a,因为x先被声明,并且a没有在z的依赖管理中声明。
这个过程是递归进行的。假如x导入了另外的pom,q,那么当解析z的时候,所有q的管理依赖看上去就都像在x中定义的一样。
当定义一个用于构建多项目的包含一些相关构件的依赖“库”时,导入依赖就十分有效。从“库”中引用一个或多个构件到项目中,是一种很常见的做法。然而,
保持项目中使用的依赖版本与库中发布的版本一致会有点麻烦。下面的模式描述了怎么生成一个供其它项目使用的“物料清单”(bom)。
项目的根元素是bom pom文件。它定义了库中创建的所有构件版本。其它要使用该库的项目必须将该pom导入到其pom文件中的<dependencymanagement>元素中。
<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”> <groupid>com.test</groupid> <artifactid>bom</artifactid> <version>1.0.0</version> <properties> <project1version>1.0.0</project1version> <project2version>1.0.0</project2version> </properties> <artifactid>project1</artifactid> <version>${project1version}</version> <artifactid>project2</artifactid> <modules> <module>parent</module> </modules>
parent子项目将bom pom作为它的父项目。这是一个简单的多项目pom。
接下来是真正的pom文件。
<parent> <artifactid>parent</artifactid> </parent> <packaging>jar</packaging> <groupid>log4j</groupid> <artifactid>log4j</artifactid> <version>${project2version}</version> <groupid>commons-logging</groupid> <artifactid>commons-logging</artifactid>
下面的例子说明了怎么在项目中使用“库”,而不必指定依赖模块的版本。
<artifactid>use</artifactid>
最后,当创建引入依赖的项目时,需要注意以下几点:
不要尝试引入在当前pom中定义的子模块pom。那会导致不能定位pom和编译失败。
绝不要声明导入其他pom作为目标pom的父项目(或者祖父项目等)的pom文件。这会导致循环解析,并触发异常。
当引用有传递性依赖的模块时,需要指定依赖模块的版本。不这样做,这些模块可能没有确定的版本,从而导致编译失败。(这在任何情况下都应该是一个最佳实践,因为它保证了模块版本的不变性)
系统范围的依赖应该是一直可用,并且maven不会去仓库中查找。系统范围依赖通常是指jdk或者vm提供的依赖。所以,系统依赖适用于这种情况:以前可以单独获取,但现在是由jdk提供的依赖。典型的例子就是jdbc标准扩展或者java认证和授权服务(jaas)。一个简单的例子如下:
… <groupid>javax.sql</groupid> <artifactid>jdbc-stdext</artifactid> <version>2.0</version> <scope>system</scope> <systempath>${java.home}/lib/rt.jar</systempath>
如果你的构件依赖于jdk的tools.jar,那么系统路径的值如下所示:
<groupid>sun.jdk</groupid> <artifactid>tools</artifactid> <version>1.5.0</version> <systempath>${java.home}/../lib/tools.jar</systempath>