Maven食谱
如果你是一个使用Maven的新手,建议你从到到位按顺序阅读本食谱,如果你是一个老油条,你可以把这份文档当成食谱,按需翻阅。
章节
- Maven是什么?
- Maven如何优化开发流程?
- 如何设置Maven?
- 如何创建第一个Maven项目?
- 如何编译项目源码?
- 如何编译测试代码并且运行单元测试?
- 如何创建JAR并且安装到本地仓库
- 什么是SNAPSHOP版本?
- 如何使用插件?
- 如何添加资源到工程?
- 如何处理资源文件中的引用?
- 如何使用其他依赖?
- 如何发布我的jar到远程仓库?
- 如何创建文档?
- 如何同时编译多个项目
Maven是什么?
Maven是一次尝试,尝试将模板套入一个项目的基础构建流程,希望套入一个基于项目最佳实践的清晰的用法模板来提高项目的可理解性和提高生产效率。
Maven实际上是一个项目管理的综合工具,包括:
- 编译 (builds)
- 文档生成 (documentation)
- 生成报告 (reporting)
- 依赖管理 (dependencies)
- SCMs (sofeware configuration management)
- 发布 (releases)
- 分发 (distribution)
Maven如何优化开发流程
Maven 通过使用标准的约定和实践来加速你的开发周期,同时让你获得更高的成功率。
我该如何设置Maven?
默认的maven配置一般是足够的,但是,如果你需要修改缓存地址(本地仓库) 或者使用一个Http proxy, 你就需要去修改配置文件。详见链接。//todo
如何创建第一个Maven项目?
我们将使用Maven的原型机制来创建我们的第一个Maven项目。原型是一种原始的模式或模型,即同类型的都是都是有这些东西构成的。在Maven中,原型是一个项目的模板,模板根据用户的输入,生成一个已经按用户需求调整的项目。现在我们将向你展示原型机制是如何工作的,但如果你想知道更多关于原型的只是,详见链接。 //todo
为了创建一个最简单的Maven项目,你可以执行以下代码
mvn -B archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DgroupId=com.mycompany.app \
-DartifactId=my-app
当你执行了上面的命令,你会发现当前目录下生成了一个叫 my-app 的文件夹,并且里面有一个pom.xml 文件。并且pom.xml 文件内容类似
<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>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
pom.xml 包含了包含了项目的的 POM(项目对象模型)。POM是Maven项目的基础单元。这点很重要,因为Maven 本质上就是以项目为中心的。简单来说,POM包含了所有关于项目的重要信息。新手建议查看POM介绍 //todo
上面这个是一个简单且包含了关键元素的POM,下面我们来认识一下她们。
- project:pom文件的顶级元素
- modelVersion:指定 POM 使用的Model版本,这个版本通常不会改变,但这个属性是必须的,为了使用者的稳定性,当Maven开发人员发现修改版本是必须的,就会有新的model版本
- groupId:指定项目所属的公司或工作室。这个属性是项目的其中一个身份标记,值类似于你的公司的全限定域名。比如说 org.apache.maven.plugin 就是Maven官方插件的组Id
- artifactId:指定项目的基本名称。首先常见的项目输出是一个jar文件。第二,生成源码包使用artifactId作为最终的文件名。一个典型的成品的名字按照如下格式命名 -. 如:myapp-1.0.jar
- packaging:指定项目输出的打包类型(如 JAR, WAR, EAR等等),它不仅仅指定了打包类型,还会影响指定的生命周期的执行过程。(生命周期我们将在下面介绍到)
- version:指定项目的版本。Maven 可以帮你进行版本管理。你可能会经常看到版本中包含了SNAPSHOT,这个约定的意思是这个版本仍然在开发阶段。
- name:指定项目名称,这个名称会出现在生成的文档里面
- url:指定这个项目的官网,同样会出现在文档
- description:这个元素为你的项目提供一个简单元素。同样也会出现在文档上
根据原型创建的项目你会看到如下的目录结构
my-app
|-- pom.xml
`-- src
|-- main
| `-- java
| `-- com
| `-- mycompany
| `-- app
| `-- App.java
`-- test
`-- java
`-- com
`-- mycompany
`-- app
`-- AppTest.java
如你所见,从原型构建的项目拥有一个POM文件,一根源码目录树,一根测试目录树。
如果你是手动创建Maven项目,我们也希望你能按照这个约定好的布局来创建目录
如何编译项目源码?
执行下面命令
mvn compile
执行了上面的命令后,你会得到类似的输出
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Quick Start Archetype
[INFO] task-segment: [compile]
[INFO] ----------------------------------------------------------------------------
[INFO] artifact org.apache.maven.plugins:maven-resources-plugin: \
checking for updates from central
...
[INFO] artifact org.apache.maven.plugins:maven-compiler-plugin: \
checking for updates from central
...
[INFO] [resources:resources]
...
[INFO] [compiler:compile]
Compiling 1 source file to <dir>/my-app/target/classes
[INFO] ----------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ----------------------------------------------------------------------------
[INFO] Total time: 3 minutes 54 seconds
[INFO] Finished at: Fri Sep 23 15:48:34 GMT-05:00 2005
[INFO] Final Memory: 2M/6M
[INFO] ----------------------------------------------------------------------------
如果你是第一次执行这条命令,Maven需要去下载所有需要的插件跟依赖,可能会慢一些。
从命令输出可以看到,被编译后的字节码放在了${basedir}/target/classes 目录中,这也是Maven约定俗成的标准。如果你是一个敏锐的冒险家,你就会发现通过使用Maven约定的规则,POM文件中你需要关注的东西其实很少,你不需要特别告诉Maven源码目录和输出目录应该在哪里,而对比起Ant, 这些东西动能你是你不得不要去做的繁琐的事情。
如何编译测试代码并且运行单元测试?
执行以下命令
mvn test
执行后你将得到如下输出
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Quick Start Archetype
[INFO] task-segment: [test]
[INFO] ----------------------------------------------------------------------------
[INFO] artifact org.apache.maven.plugins:maven-surefire-plugin: \
checking for updates from central
...
[INFO] [resources:resources]
[INFO] [compiler:compile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources]
[INFO] [compiler:testCompile]
Compiling 1 source file to C:\Test\Maven2\test\my-app\target\test-classes
...
[INFO] [surefire:test]
[INFO] Setting reports dir: C:\Test\Maven2\test\my-app\target/surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
[surefire] Running com.mycompany.app.AppTest
[surefire] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0 sec
Results :
[surefire] Tests run: 1, Failures: 0, Errors: 0
[INFO] ----------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ----------------------------------------------------------------------------
[INFO] Total time: 15 seconds
[INFO] Finished at: Thu Oct 06 08:12:17 MDT 2005
[INFO] Final Memory: 2M/8M
我们可以注意到上面的输出中
- Maven 下载了其他的依赖。这些依赖跟插件是执行这些测试所必须的(如果已经下载过了就不会重新下载了)
- 在编译和执行测试之前,Maven需要编译源代码(但是这个例子中,源码的编译我们已经在上一步 mvn compile 做过了,并且没有修改过,所以Maven输出了没有任何变化,延用已经编译好的字节码)
如果你仅仅是想编译你的测试代码而不执行,你可以执行下面的命令
mvn test-compile
如何创建JAR并且安装到本地仓库
生成一个JAR文件是很简单的,只要执行下面的命令即可
mvn package
可以看到你的项目的pom.xml中的packaging 元素被设置成了jar。这个属性决定了上面这个命令的输出类型,执行后,你可以在 ${basedir}/target 目录中看到生成的jar包。
如果你想安装到本地目录,执行下面的命令(默认的本地仓库路径是${user.home}/.m2/repository)
mvn install
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Quick Start Archetype
[INFO] task-segment: [install]
[INFO] ----------------------------------------------------------------------------
[INFO] [resources:resources]
[INFO] [compiler:compile]
Compiling 1 source file to <dir>/my-app/target/classes
[INFO] [resources:testResources]
[INFO] [compiler:testCompile]
Compiling 1 source file to <dir>/my-app/target/test-classes
[INFO] [surefire:test]
[INFO] Setting reports dir: <dir>/my-app/target/surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
[surefire] Running com.mycompany.app.AppTest
[surefire] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.001 sec
Results :
[surefire] Tests run: 1, Failures: 0, Errors: 0
[INFO] [jar:jar]
[INFO] Building jar: <dir>/my-app/target/my-app-1.0-SNAPSHOT.jar
[INFO] [install:install]
[INFO] Installing <dir>/my-app/target/my-app-1.0-SNAPSHOT.jar to \
<local-repository>/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-SNAPSHOT.jar
[INFO] ----------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ----------------------------------------------------------------------------
[INFO] Total time: 5 seconds
[INFO] Finished at: Tue Oct 04 13:20:32 GMT-05:00 2005
[INFO] Final Memory: 3M/8M
[INFO] ----------------------------------------------------------------------------
需要注意的是,surefire 插件(即执行测试的插件)会在文件中查找需要执行的测试样例,查找的规则是根据约定的文件名查找。默认的测试文件名包括:
- **/*Test.java
- */Test.java
- **/*TestCase.java
并且会排出一下名字
- **/Abstract*Test.java
- **/Abstract*TestCase.java
到目前为止呢,你已经走过了初始化,编译,测试,打包,安装这些道路。而这些
是Maven项目基本上都需要做的,这些事情仅仅只需要18行的pom.xml就能完成,就问你厉害不厉害。相比Ant,你要完成这些工作,你至少需要一倍的代码。而且通过这个pom你不仅仅能完成这些工作。
这里还有一个比较重要的的功能,就是生成说明网页
mvn site
或者是清楚所有生成的文件
mvn clean
什么是SNAPSHOP版本?
<project xmlns="http://maven.apache.org/POM/4.0.0"
...
<groupId>...</groupId>
<artifactId>my-app</artifactId>
...
<version>1.0-SNAPSHOT</version>
<name>Maven Quick Start Archetype</name>
...
SNAPSHOT 意味着开发分支的最新版本的代码,并且提供者没有抱着这个代码是稳定且不变的。相反的,RELEASE 版本则是稳定不变的。
如何使用插件?
如果你想自定义编译过程,通过增加或修改插件的配置就能做到
下面这个例子中,我们会配置java编译器允许JDK5.0的代码。
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
...
你会注意到所有的Maven插件看起来跟依赖差不多。在某种程度上的确如此。这个插件会自动下载和使用,如果你制定了特定的版本,他也会使用指定的版本,否则就是最新的稳定版
configuration 元素将给定的参数应用到编译插件的每一个goal(目标)中。你也可以增加新的目标,更多详情参考编译生命周期。 //todo
如果想要查找可用插件以及插件的可配置项,可以通过这里查找 //todo
如何添加资源到工程?
一个常见功能,我们在上面已经提及了, mvn package,它不仅会打包项目,还可以打包资源文件。我们只要按照约定的目录放置就可以了。
在下面的例子中,我们在 basedir/src/main/resources目录中放置了一些我们希望打包进jar包的资源文件。Maven约定了在 b a s e d i r / s r c / m a i n / r e s o u r c e s 目 录 中 放 置 了 一 些 我 们 希 望 打 包 进 j a r 包 的 资 源 文 件 。 M a v e n 约 定 了 在 {basedir}/src/main/resoucrs 下面所有文件夹或文件都会被一起打包。
my-app
|-- pom.xml
`-- src
|-- main
| |-- java
| | `-- com
| | `-- mycompany
| | `-- app
| | `-- App.java
| `-- resources
| `-- META-INF
| `-- application.properties
`-- test
`-- java
`-- com
`-- mycompany
`-- app
`-- AppTest.java
所以你可以看到例子中,我们有一个META-INF的文件里,里面有一个 application.properties文件。如果你将导出的jar包解开,你会看到如下的结构
|-- META-INF
| |-- MANIFEST.MF
| |-- application.properties
| `-- maven
| `-- com.mycompany.app
| `-- my-app
| |-- pom.properties
| `-- pom.xml
`-- com
`-- mycompany
`-- app
`-- App.class
如你所见,${basedir}/src/main/resources 里面的内容可以在解压后的jar包根目录看到同样的目录结构。你还会发现一些其他文件,如META-INF/MAINFEST.MF 和 pom.xml 以及 pom.properties 文件。这些是Maven生成的标准文件。你可以自己生成你自己的mainfest文件,但如果你没有,Maven会默认替你生成一个(同样你也可以自定义Maven如何生成这个文件内容)。pom.xml 和 pom.properties 文件被放进了包中,这是为了让这个应用可以自描述,并且允许你在应用中可以使用这些属性,如果有这个需求的话。一个简单的场景就是在你的应用中显示当前的应用版本。使用pom.xml文件会需要你使用一些xml的包,但如果是pom.properties, 你就可以直接通过java api 获取到这些属性了。
同样的,如果你想为你的测试树的代码添加资源文件,可以再测试树下创建resources文件夹。所以当前的目录结构如下
my-app
|-- pom.xml
`-- src
|-- main
| |-- java
| | `-- com
| | `-- mycompany
| | `-- app
| | `-- App.java
| `-- resources
| `-- META-INF
| |-- application.properties
`-- test
|-- java
| `-- com
| `-- mycompany
| `-- app
| `-- AppTest.java
`-- resources
`-- test.properties
在单元测试中,你可以通过这样的方式来获取到资源文件内容
...
// Retrieve resource
InputStream is = getClass().getResourceAsStream( "/test.properties" );
// Do something with the resource
...
如何处理资源文件中的引用?
有时候一个资源文件会包含一些属性,这些属性会在编译时被用到。Maven为了处理这种场景,采取的做法是,采用一个取值符号来引用资源文件中的属性值
${<属性名>}
这个属性可以定义在pom.xml、settings.xml、 其他properties文件或是系统属性
为了让Maven 在拷贝过程中替换这些引用,只要在pom.xml中 设置filtering 为 true即可,参考如下配置
<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>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
你会发现我们不得不增加 build, resources 这些节点之前不需要的节点。除此意外,我们还需要显示指明resources的路径为 src/main/resources。所有的这些信息之前Maven都为我们提供了默认值,但我们这里为了覆盖 filtering这个值为false, 不得不重写这些默认值。
如何引用这些属性值呢?
引用pom.xml 使用 project.∗∗,如 p r o j e c t . ∗ ∗ , 如 {project.name} project.version p r o j e c t . v e r s i o n {project.build.finalName}
我们没有显示指明的属性也可以获取
引用settings.xml 使用 settings.∗∗,如 s e t t i n g s . ∗ ∗ , 如 {settings.localRepository}
下面是一个例子
# application.properties
application.name=${project.name}
application.version=${project.version}
message=${my.filter.value}
command.line.prop=${command.line.prop}
执行下面命令执行处理资源阶段
mvn process-resources "-Dcommand.line.prop=hello again"
如何使用其他依赖?
你可能已经发现了我们一开始的pom.xml文件里面就有 dependencies 这个节点。我们接下来会讲更过关于依赖的事情。如果你想知道得彻底,可以查看依赖机制这篇文章 //todo
dependencies 节点列出来所有该项目需要的外部依赖(不管这些依赖是在编译期需要还是说在测试阶段,运行阶段或其他)现在我们仅仅需要junit,如下面的例子
<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>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
对于每一个外部依赖,你至少需要定义四个属性
- groupId
- artifactId
- version
- scope
groupId artifactId version 唯一标记一个组件, scope指明你的项目如何使用这个依赖,scope的值可以是 compile test runtime 。
Maven 引用这些组件的时候,首先会在本地仓库中查找,找不到再去远程仓库下载到本地仓库。默认的远程仓库是 http://repo.maven.apache.org/maven2/ 你可以修改这个远程仓库的地址,比如国内的大厂的地址,或是你自己公司的仓库。由于墙的缘故,默认的仓库速度会很慢,除非翻墙。
我们可以再这个网址搜索自己需要组件 https://mvnrepository.com/
然后拷贝对应的组件配置到dependencies 节点下面,然后执行下面命令下载打包
mvn compile
如何发布我的jar到远程仓库
如果想发布自己的组件到远程仓库,你需要配置仓库地址到pom.xml 并且在settings.xml文件中补充授权身份验证信息
下面这个例子使用scp 和username/password 形式的权限认证
pom.xml
<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>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
<build>
<filters>
<filter>src/main/filters/filters.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<!--
|
|
|
-->
<distributionManagement>
<repository>
<id>mycompany-repository</id>
<name>MyCompany Repository</name>
<url>scp://repository.mycompany.com/repository/maven2</url>
</repository>
</distributionManagement>
</project>
setting.xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
...
<servers>
<server>
<id>mycompany-repository</id>
<username>jvanzyl</username>
<!-- Default value is ~/.ssh/id_dsa -->
<privateKey>/path/to/identity</privateKey> (default is ~/.ssh/id_dsa)
<passphrase>my_key_passphrase</passphrase>
</server>
</servers>
...
</settings>
强烈建议使用私钥方式登录,不然每次都要输密码,真的会很烦。
如何创建文档?
为了让你快速使用了解Maven的文档系统,你可以执行下面的命令,生成一个精心准备的原型
mvn archetype:generate
-DarchetypeGroupId=org.apache.maven.archetypes
-DarchetypeArtifactId=maven-archetype-site
-DgroupId=com.mycompany.app
-DartifactId=my-app-site
详情查看这个链接 //todo
如何同时编译多个项目
首先,我们需要添加一个父级的pom.xml文件在这两个项目同级目录上,类似如下的结构
+- pom.xml
+- my-app
| +- pom.xml
| +- src
| +- main
| +- java
+- my-webapp
| +- pom.xml
| +- src
| +- main
| +- webapp
你的pom.xml文件大概要长这样子
<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>com.mycompany.app</groupId>
<artifactId>app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>my-app</module>
<module>my-webapp</module>
</modules>
</project>
然后分别在两个项目的pom.xml 中添加配置,如下
<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">
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>app</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
...
然后在my-webapp/pom.xml中声明 my-webapp 需要依赖 my-app模块
...
<dependencies>
<dependency>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
...
</dependencies>
然后运行一下命令
mvn verify
执行后你会发现 生成了一个War包 my-webapp.war 在 my-webapp/target/ 下面。
这个war包的内容大概如下
$ jar tvf my-webapp/target/my-webapp-1.0-SNAPSHOT.war
0 Fri Jun 24 10:59:56 EST 2005 META-INF/
222 Fri Jun 24 10:59:54 EST 2005 META-INF/MANIFEST.MF
0 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/
0 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/com.mycompany.app/
0 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/com.mycompany.app/my-webapp/
3239 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/com.mycompany.app/my-webapp/pom.xml
0 Fri Jun 24 10:59:56 EST 2005 WEB-INF/
215 Fri Jun 24 10:59:56 EST 2005 WEB-INF/web.xml
123 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/com.mycompany.app/my-webapp/pom.properties
52 Fri Jun 24 10:59:56 EST 2005 index.jsp
0 Fri Jun 24 10:59:56 EST 2005 WEB-INF/lib/
2713 Fri Jun 24 10:59:56 EST 2005 WEB-INF/lib/my-app-1.0-SNAPSHOT.jar
他是如何工作的?首先,父pom.xml 指定了打包类型为pom, 并且定义了一系列需打包的模块。这告诉Maven 需要对这些项目模块都运行对应的操作。然后我们告诉了Maven my-webapp需要依赖my-app包。这确保了my-app会比my-webapp先编译,并且会被放置到library 文件夹中。
你可能注意到 junit 包没有被放入 war的lib中,因为我们将她的scope设置成了test。