文章目录
  1. 1. 概述
    1. 1.1. 包含的元素
      1. 1.1.1. Basics
      2. 1.1.2. build Settings
      3. 1.1.3. More project information
      4. 1.1.4. Environment Setting
  2. 2. 注意

pom作为项目对象模型(Project Object Model),是maven的一个基本单元。它是一个包含项目信息和构建配置的xml文件。主要描述了项目:包括配置文件;开发者需要遵循的规则,缺陷管理系统,组织和licenses,项目的url,项目的依赖性,以及其他所有的项目相关因素。

概述

下面给出一个pom.xml的例子,注意其中的modelVersion是4.0.0,这是当前仅有的可以被Maven2&3同时支持的POM版本,它是必须的。

<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>

  <!-- The Basics -->
  <groupId>...</groupId>
  <artifactId>...</artifactId>
  <version>...</version>
  <packaging>...</packaging>
  <dependencies>...</dependencies>
  <parent>...</parent>
  <dependencyManagement>...</dependencyManagement>
  <modules>...</modules>
  <properties>...</properties>

  <!-- Build Settings -->
  <build>...</build>
  <reporting>...</reporting>

  <!-- More Project Information -->
  <name>...</name>
  <desdescriptioncription>...</description>
  <url>...</url>
  <inceptionYear>...</inceptionYear>
  <licenses>...</licenses>
  <organization>...</organization>
  <developers>...</developers>
  <contributors>...</contributors>

  <!-- Environment Settings -->
  <issueManagement>...</issueManagement>
  <ciManagement>...</ciManagement>
  <mailingLists>...</mailingLists>
  <scm>...</scm>
  <prerequisites>...</prerequisites>
  <repositories>...</repositories>
  <pluginRepositories>...</pluginRepositories>
  <distributionManagement>...</distributionManagement>
  <profiles>...</profiles>
</project>

包含的元素

Basics

  1. modelVersion: 描述这个POM文件遵从哪个版本的项目描述符
  2. groupId: 项目或者组织的唯一标志,并且配置时生成路径也是由此生成,如org.myproject.mojo生成的相对路径为:/org/myproject/mojo
  3. artifactId: 项目的通用名称
  4. version: 项目的版本
  5. classifier: 用于区分从同一个pom编译出来的但是内容不同的同名包,例如同一个工程编译出两个artifact,一个支持jdk1.5一个支持jdk1.4,那么就可以使用这个来命名为jdk15和jdk14来区分,它如果出现在包名中,那么它必须跟在版本号后。还有一种情况是将一个工程的一些次要artifact附到主要artifact中,就可以使用这个来区分,例如一个工程产生source,javadoc,class三种东西,那么就可以使用不同的classifier来分别标识这些东西
  6. packaging: 打包机制,如pom,jar,maven-plugin,ejb,war,ear,rar,par
  7. parent: 如果一个工程是parent或者aggregation(即mutil-module的)的,那么必须在packing赋值为pom,child工程从parent继承的包括:dependencies,developers,contributors,plugin lists,reports lists,plugin execution with matching ids,plugin configuration

    <parent>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>my-parent</artifactId>
        <version>2.0</version>
        <relativePath>../my-parent</relativePath>
    </parent>
    
  8. Dependencies: 项目依赖列表

    <dependencies>
        <dependency>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-embedder</artifactId>
          <version>2.0</version>
          <!--默认为jar,类型,常用如:jar,ejb-client,test-jar,可以设置plugins中的extensions值为true后在增加新类型-->
          <type>jar</type>
          <!--是用来指定当前包的依赖范围-->
          <!--compile-默认的,compile scope在所有classpaths内有效,这些dependencies将会传播到项目中 -->
          <!--provided-指示jdk或者某个容器可以提供他,它只在compilation和test的classpaths有效,而且不会传播的 -->
          <!--runtime-指示这个dependency在编译过程是不必要的,但是执行需要,在test和runtime的classpaths有效,在compile的classpaths无效 -->
          <!--test-指示这个dependency在一般程序运行是无效的,但是在test的compilation和execution是有效的 -->
          <!--system-跟provided类似,但是这种dependency必须人工明确地制定。这种依赖不会在repository中查找。 -->
          <scope>test</scope>
          <!--设置指依赖是否可选,默认为false,即子项目默认都继承,为true,则子项目必需显示的引入,与dependencyManagement里定义的依赖类似 。-->
          <optional>true</optional>
    
          <!--如果X需要A,A包含B依赖,那么X可以声明不要B依赖,只要在exclusions中声明exclusion。optional是不会install或者使用B,而exclusion是将B从依赖树中是删除。-->
          <exclusions>
            <exclusion>
              <groupId>org.apache.maven</groupId>
              <artifactId>maven-core</artifactId>
            </exclusion>
          </exclusions>
        </dependency>
        ...
    </dependencies>
    
  9. dependencyManagement: 用于帮助管理children的dependencies。例如如果parent使用dependencyManagement定义一个dependencyon junit:junit:4.0,那么它的children就可以只引用groupId和artifactId,而version就可以通过parent来设置。好处就是集中管理依赖详情

  10. modules:集成多模块。outer-module没有必需考虑inner-module的dependencies,当列出modules的时候,modules的顺序是不重要的,因为maven会自动根据依赖关系来拓扑排序

  11. properties:为pom定义一些常量,在pom中的其它地方可以直接引用。

    1、访问自定义的内容
       <properties>
          <file.encoding>UTF-8</file_encoding>
          <java.source.version>1.5</java_source_version>
          <java.target.version>1.5</java_target_version>
       </properties>
       访问方式: ${file.encoding}
    2、访问pom中的内容
        <project><version>1.0</version></project>
       访问方式: ${project.version}
    3、访问settings.xml中内容
       访问方式: ${settings.offline}
    4、访问环境变量
       访问方式: ${env.Path}
    

build Settings

  1. build:

    <build>
      <!--默认的目标,必须跟命令行上的参数相同例如jar:jar,或者与时期(parse)相同,例如install-->
      <defaultGoal>install</defaultGoal>
      <!--指定build target目标的目录,默认为${basedir}/target,即项目根目录下的target-->
      <directory>${basedir}/target</directory>
      <!--指定去掉后缀名后的工程名字,例如:默认为${artifactId}-${version}-->
      <finalName>${artifactId}-${version}</finalName>
    
      <!--用于定义指定filter属性文件位置,例如filter元素赋值filters/filter1.properties,那么这个文件里面就可以定义name=value对,这个name=value对的值就可以在工程pom中通过${name}引用,默认的filter目录是${basedir}/src/main/filters/-->
      <filters>
        <filter>filters/filter1.properties</filter>
      </filters>
    
      <!--描述工程中资源的位置-->
      <resources>
          <resource>
            <!--指定build资源到哪个目录,默认是base directory-->
            <targetPath>META-INF/plexus</targetPath>
            <!--指定是否将filter文件(即上面说的filters里定义的*.property文件)的变量值在这个resource文件有效,例如上面就指定那些变量值在configuration文件无效-->
            <filtering>false</filtering>
            <!--指定属性文件的目录,build的过程需要找到它,并且将其放到targetPath下。默认的directory是${basedir}/src/main/resources-->
            <directory>${basedir}/src/main/plexus</directory>
            <!--指定包含文件的patterns,符合样式并且在directory目录下的文件将会是包含进project的资源文件-->
            <includes>
              <include>configuration.xml</include>
            </includes>
            <!--指定不包含在内的patterns,如果includes与excludes有冲突,那么excludes胜利,那些符合冲突样式的文件还是不会包含进来的-->
            <excludes>
              <exclude>**/*.properties</exclude>
            </excludes>
          </resource>
      </resources>
      <!--这个模块包含测试资源元素,其内容定义与resources类似。不同的一点是默认的测试资源路径是${basefir}/src/test/resources,测试资源是不部署的。-->
      <testResources>
          ...
      </testResources>
    
      <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.0</version>
            <!--true or false,决定是否要load这个plugin的extensions-->
            <extensions>false</extensions>
            <!--是否让子pom继承true or false-->
            <inherited>true</inherited>
            <!--通常用于私有不开源的plugin,不能够详细了解plugin的内部工作原理,但使plugin满足需要满足的properties-->                
            <configuration>
              <classifier>test</classifier>
            </configuration>
            <!--与pom基础的dependencies的结构和功能都相同,只是plugin的dependencies用于plugin,而pom的dependencies用于本身这个工程,-->
            <!--在plugin的dependencies主要用于改变plugin原来的dependencies,例如排除一些用不到的dependency或者修改dependency的版本等-->
            <dependencies>...</dependencies>
            <!--plugin也有很多个目标,每个目标具有不同的配置,executions就是设定plugin的目标-->
            <executions>
                <execution>
                    <!--标识符-->
                    <id>echodir</id>
                    <!--里面列出一系列的goal元素-->
                    <goals>
                      <goal>run</goal>
                    </goals>
                    <!--声明goals执行的时期-->
                    <phase>verify</phase>
                    <!--是否传递execution到子pom-->
                    <inherited>false</inherited>
                    <!--设置execution下列表的goals(也就是上面设置的)的设置,而不是plugin所有的goals的设置-->
                    <configuration>
                      <tasks>
                        <echo>Build Dir: ${project.build.directory}</echo>
                      </tasks>
                    </configuration>
                  </execution>
                </executions>
            </executions>
          </plugin>
      </plugins>
    
        <!--用于管理plugin,与pom build里的plugins区别是,这里的plugin是列出来,然后让子pom来决定是否引用的-->
      <pluginManagement>
          <plugins>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-jar-plugin</artifactId>
              <version>2.2</version>
              <executions>
                <execution>
                  <id>pre-process-classes</id>
                  <phase>compile</phase>
                  <goals>
                    <goal>jar</goal>
                  </goals>
                  <configuration>
                    <classifier>pre-process</classifier>
                  </configuration>
                </execution>
              </executions>
            </plugin>
          </plugins>
       </pluginManagement>
        <!--下面几个元素只在parent bulid element里面定义,他们设置多种路径结构,他们并不在profile里,所以不能通过profile来修改-->
        sourceDirectory>${basedir}/src/main/java</sourceDirectory>
        <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
        <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
        <outputDirectory>${basedir}/target/classes</outputDirectory>
        <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
        <!--它们是一系列build过程中要使用的产品,他们会包含在running bulid‘s classpath里面。他们可以开启extensions,也可以通过提供条件来激活plugins。简单来讲,extensions是在build过程被激活的产品 -->
        <extensions>
            <extension>
            <groupId>org.apache.maven.wagon</groupId>
            <artifactId>wagon-ftp</artifactId>
            <version>1.0-alpha-3</version>
            </extension>
        </extensions>
      ...
    </build>
    
  2. reporting:reporting包含site生成阶段的一些元素,某些maven plugin可以生成reports并且在repoting下配置。例如javadoc,maven site等,在reporting下配置reprot plugin的方法与build几乎一样,最不同的是:build的plug-in goals在executions下设置,而reporting的configures goals在reportset。更微妙的不同是reporting下的plugin configuration works as a build plugin configuration,但是相反是不对的(即build plugin configuration does not affect a reporting plugin)。

    <reporting>
      <!--默认的dir变成:${basedir}/target/site-->
      <outputDirectory>${basedir}/target/site</outputDirectory>
      <plugins>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>2.0.1</version>
          <!--设置execution goals,相当于build里面的executions。不同的是不能够bind a report to another phase,只能够是site-->
          <reportSets>
            <reportSet>
              <id>sunlink</id>
              <reports>
                <report>javadoc</report>
              </reports>
              <inherited>true</inherited>
              <configuration>
                <links>
                  <link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
                </links>
              </configuration>
            </reportSet>
          </reportSets>
        </plugin>
      </plugins>
    </reporting>
    

More project information

  1. name:用户描述项目的名称,项目除了artifactId外,可以定义多个名称
  2. description:项目描述
  3. url: 当前项目的主页的URL。
  4. inceptionYear:起始年份
  5. licenses:定义使用许可规范

    <licenses>
      <license>
        <name>Apache License, Version 2.0</name>
        <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
        <distribution>repo</distribution>
        <comments>A business-friendly OSS license</comments>
      </license>
    </licenses>
    
  6. organization:很多工程都受到某些组织运行,这里设置基本信息

    <organization>
       <name>Codehaus Mojo</name>
       <url>http://mojo.codehaus.org</url>
    </organization>
    
  7. developers: 定义开发者信息

    <developers>
        <developer>
          <id>eric</id>
          <name>Eric</name>
          <email>eredmond@codehaus.org</email>
          <url>http://eric.propellors.net</url>
          <organization>Codehaus</organization>
          <organizationUrl>http://mojo.codehaus.org</organizationUrl>
          <roles>
            <role>architect</role>
            <role>developer</role>
          </roles>
          <timezone>-6</timezone>
          <properties>
            <picUrl>http://tinyurl.com/prv4t</picUrl>
          </properties>
        </developer>
    </developers>        
    
  8. contributors:跟developer差不多,只是contributors是副的工作人员,不过良好工程应该需要更多的contributors而不是developer

Environment Setting

  1. issueManagement: 定义使用的项目缺陷跟踪系统,主要用于生成项目文档

    <issueManagement>
        <system>Bugzilla</system>
        <url>http://127.0.0.1/bugzilla/</url>
    </issueManagement>
    
  2. ciManagement: 配置持续集成构建的相关信息,比如用于配置的特定程序Continuum, Cruise Control, etc。maven捕获一些经常重发生的配置,在notifier元素里配置。

    <ciManagement>
        <system>continuum</system>
        <url>http://127.0.0.1:8080/continuum</url>
        <notifiers>
          <notifier>
            <type>mail</type>
            <sendOnError>true</sendOnError>
            <sendOnFailure>true</sendOnFailure>
            <sendOnSuccess>false</sendOnSuccess>
            <sendOnWarning>false</sendOnWarning>
            <configuration><address>continuum@127.0.0.1</address></configuration>
          </notifier>
        </notifiers>
    </ciManagement>
    
  3. mailingLists: 是一个和项目相关人员保持联系的工具,主要供开发者和用户使用。

    <mailingLists>
        <mailingList>
          <name>User List</name>
          <subscribe>user-subscribe@127.0.0.1</subscribe>
          <unsubscribe>user-unsubscribe@127.0.0.1</unsubscribe>
          <post>user@127.0.0.1</post>
          <archive>http://127.0.0.1/user/</archive>
          <otherArchives>
            <otherArchive>http://base.google.com/base/1/127.0.0.1</otherArchive>
          </otherArchives>
        </mailingList>
    </mailingLists>    
    

    subscribe, unsubscribe: There elements specify the email addresses which are used for performing the relative actions To subscribe to the user list above, a user would send an email to user-subscribe@127.0.0.1.

    archive: This element specifies the url of the archive of old mailing list emails, if one exists. If there are mirrored archives, they can be specified under otherArchives.

    post: The email address which one would use in order to post to the mailing list. Note that not all mailing lists have the ability to post to (such as a build failure list).

  4. scm: Software Configuration Management。

    <scm>
        <!--连接字符串,developerConnection有写权限,url格式scm:[provider]:[provider_specific] -->
        <connection>scm:svn:http://127.0.0.1/svn/my-project</connection>
        <developerConnection>scm:svn:https://127.0.0.1/svn/my-project</developerConnection>
        <!--指定项目tag,HEAD默认-->
        <tag>HEAD</tag>
        <!--公开可以浏览的repository-->
        <url>http://127.0.0.1/websvn/my-project</url>
    </scm>
    
  5. prerequisites: 描述当前项目的编译环境的先决条件.如果不满足,maven会在事件开始之前失败,在pom4.0,唯一的首要条件是maven元素

    <prerequisites>
        <maven>2.0.6</maven>
    </prerequisites>
    
  6. repositories: pom里面的仓库与setting.xml里的仓库功能是一样的。主要的区别在于,pom里的仓库是个性化的。比如一家大公司里的setting文件是公用 的,所有项目都用一个setting文件,但各个子项目却会引用不同的第三方库,所以就需要在pom里设置自己需要的仓库地址。要成为maven2的repository artifact,必须具有pom文件在$BASE_REPO/groupId/artifactId/version/artifactId-version.pom,BASE_REPO可以是本地,也可以是远程的。repository元素就是声明那些去查找的repositories

    <repositories>
        <repository>
          <!--是artifact的两种policies,pom可以选择哪种政策有效。-->
          <releases>
            <!--指定两种类型是否可用,true or false-->
            <enabled>false</enabled>
            <!--说明更新发生的频率always 或者 never 或者 daily(默认的)或者 interval:X(X是分钟数)-->
            <updatePolicy>always</updatePolicy>
            <!--当Maven的部署文件到仓库中,它也部署了相应的checksum files。您可以选择ignore, fail, or warn on missing or incorrect checksums。-->
            <checksumPolicy>warn</checksumPolicy>
          </releases>
          <snapshots>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
            <checksumPolicy>fail</checksumPolicy>
          </snapshots>
          <id>codehausSnapshots</id>
          <name>Codehaus Snapshots</name>
          <url>http://snapshots.maven.codehaus.org/maven2</url>
          <!--maven1.x与maven2有不同的layout,所以可以声明为default或者是legacy(遗留方式maven1.x)-->
          <layout>default</layout>
        </repository>
    </repositories>
    
  7. pluginRepositories: 与Repositories具有类似的结构,只是Repositories是dependencies的home,而这个是plugins 的home
  8. distributionManagement: 管理distribution和supporting files。

    <distributionManagement>
    ...
        <!--其他项目为了抓取本项目的pom’s artifact而指定的url,就是说告诉pom upload的地址也就是别人可以下载的地址。 -->
        <downloadUrl>http://mojo.codehaus.org/my-project</downloadUrl>
        <!--这里的状态不要受到我们的设置,maven会自动设置project的状态-->
        <!--有效的值有none:没有声明状态,pom默认的;-->
        <!--    converted:本project是管理员从原先的maven版本convert到maven2的;-->
        <!--partner:以前叫做synched,意思是与partner repository已经进行了同步;-->
        <!--deployed:至今为止最经常的状态,意思是制品是从maven2 instance部署的,人工在命令行deploy的就会得到这个;-->
        <!--verified:本制品已经经过验证,也就是已经定下来了最终版。 -->
        <status>deployed</status>
    
        <!--声明deploy过程中current project会如何变成repository,说明部署到repository的信息-->
        <repository>
          <!--指定是否产生一个唯一性的version number还是使用address里的其中version部分-->
          <uniqueVersion>false</uniqueVersion>
          <!--唯一性的id-->    
          <id>corp1</id>
          <!--可读性的name -->
          <name>Corporate Repository</name>
          <!--说明location和transport protocol-->
          <url>scp://repo/maven2</url>
          <layout>default</layout>
        </repository>
        <snapshotRepository>
          <uniqueVersion>true</uniqueVersion>
          <id>propSnap</id>
          <name>Propellors Snapshots</name>
          <url>sftp://propellers.net/maven</url>
          <layout>legacy</layout>
        </snapshotRepository>
    
        <!--声明如何部署project‘s 的site和document-->
        <site>
            <id>mojo.website</id>
            <name>Mojo Website</name>
            <url>scp://beaver.codehaus.org/home/projects/mojo/public_html/</url>
        </site>
    
        <!--说明工程的变更,在这里警告使用者当心工程被重命名了等信息。重新指定id和名称,并且写个message注明备注 -->
        <relocation>
            <groupId>org.apache</groupId>
            <artifactId>my-project</artifactId>
            <version>1.0</version>
            <message>We have moved the Project under Apache</message>
        </relocation>
    </distributionManagement>
    
  9. profiles: pom4.0的一个新特性就是具有根据environment来修改设置的能力。它包含可选的activation(profile的触发器)和一系列的changes。例如test过程可能会指向不同的数据库(相对最终的deployment)或者不同的dependencies或者不同的repositories,并且是根据不同的JDK来改变的。

      <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>
    

    只需要其中一个成立就可以激活profile,如果第一个条件满足了,那么后面就不会在进行匹配

注意

  1. Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式。通常会在一个组织或者项目的最顶层的父POM 中看到dependencyManagement 元素。使用pom.xml 中的dependencyManagement 元素能让
    所有在子项目中引用一个依赖而不用显式的列出版本号。Maven 会沿着父子层次向上走,直到找到一个拥有dependencyManagement 元素的项目,然后它就会使用在这个dependencyManagement 元素中指定的版本号。这样做的好处就是:如果有多个子项目都引用同一样依赖,则可以避免在每个使用的子项目里都声明一个版本号,这样当想升级或切换到另一个版本时,只需要在顶层父容器里更新,而不需要一个一个子项目的修改 ;另外如果某个子项目需要另外的一个版本,只需要声明version就可。dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显式的声明需要用的依赖
文章目录
  1. 1. 概述
    1. 1.1. 包含的元素
      1. 1.1.1. Basics
      2. 1.1.2. build Settings
      3. 1.1.3. More project information
      4. 1.1.4. Environment Setting
  2. 2. 注意