Maven实战之Quick Start

Introduction

Maven是一个异常强大的构建工具,可以帮咱们自动化构建过程,从清理、编译、测试到生成报告,再到打包和部署。经过Maven,咱们只须要输入简单的命令(如mvn clean install),就会帮咱们处理繁琐的任务。Maven最大化的消除了构建的重复,抽象了构建生命周期,而且为绝大部分的构建任务提供了已实现的插件。好比说测试,咱们只须要遵循Maven的约定编写好测试用例,当咱们运行构建的时候,这些测试便会自动运行。除此以外,Maven能帮助咱们标准化构建过程。在Maven以前,十个项目可能有十种构建方式,但经过Maven,全部项目的构建命令都是简单一致的。有利于促进项目团队的标准化。java

Maven是笔者接触的第一个脱离于IDE的命令行构建工具,笔者以前一直是基于Visual Studio下进行Windows驱动开发,并非很能明白Builder与IDE之间的区别。依赖大量的手工操做。编译、测试、代码生成等工做都是相互独立的,很难一键完成全部工做。手工劳动每每意味着低效,意味着容易出错。很难在项目中统一全部的IDE配置,每一个人都有本身的喜爱。也正是因为这个缘由,一个在机器A上能够成功运行的任务,到了机器B的IDE中可能就会失败。linux

Make

Make将本身和操做系统绑定在一块儿了。也就是说,使用Make,就不能实现(至少很难)跨平台的构建,这对于Java来讲是很是不友好的。此外,Makefile的语法也成问题,不少人抱怨Make构建失败的缘由每每是一个难以发现的空格或Tab使用错误。git

Ant

  • 和Make同样,Ant也都是过程式的,开发者显式地指定每个目标,以及完成该目标所须要执行的任务。针对每个项目,开发者都须要从新编写这一过程,这里其实隐含着很大的重复。Maven是声明式的,项目构建过程和过程各个阶段所需的工做都由插件实现,而且大部分插件都是现成的,开发者只须要声明项目的基本元素,Maven就执行内置的、完整的构建过程。这在很大程度上消除了重复。github

  • Ant是没有依赖管理的,因此很长一段时间Ant用户都不得不手工管理依赖,这是一个使人头疼的问题。幸运的是,Ant用户如今能够借助Ivy管理依赖。而对于Maven用户来讲,依赖管理是理所固然的,Maven不只内置了依赖管理,更有一个可能拥有全世界最多Java开源软件包的中央仓库,Maven用户无须进行任何配置就能够直接享用。web

Usage

Installation

可从apache官方下载最新的Maven 压缩包,解压便可。而后设置下系统的环境变量。以下所示:apache

  • M2HOME:maven安装目录服务器

  • Path:追加maven安装目录下的bin目录网络

在用户目录下,咱们能够发现.m2文件夹。默认状况下,该文件夹下放置了Maven本地仓库.m2/repository。全部的Maven构件(artifact)都被存储到该仓库中,以方便重用。默认状况下,~/.m2目录下除了repository仓库以外就没有其余目录和文件了,不过大多数Maven用户须要复制M2HOME/conf/settings.xml文件到~/.m2/settings.xmlapp

Commands List

本节列举出部分经常使用的Maven命令:dom

mvn -v 查看maven版本

mvn compile 编译

mvn test 测试

mvn package 打包

mvn clean 删除target

mvn install 安装jar包到本地仓库中

  • 建立一个新工程

mvn archetype:generate -DgroupId=co.hoteam -DartifactId=Zigbee -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Pom

就像Make的Makefile,Ant的build.xml同样,Maven项目的核心是pom.xml。

首先建立一个名为hello-world的文件夹,打开该文件夹,新建一个名为pom.xml的文件,输入其内容以下:

<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>hello-world</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Maven Hello World Project</name>
</project>
  • 代码的第一行是XML头,指定了该xml文档的版本和编码方式。紧接着是project元素,project是全部pom.xml的根元素,它还声明了一些POM相关的命名空间及xsd元素,虽然这些属性不是必须的,但使用这些属性可以让第三方工具(如IDE中的XML编辑器)帮助咱们快速编辑POM。

  • 根元素下的第一个子元素modelVersion指定了当前POM模型的版本,对于Maven2及Maven 3来讲,它只能是4.0.0。这段代码中最重要的是groupId,artifactId和version三行。这三个元素定义了一个项目基本的坐标,在Maven的世界,任何的jar、pom或者war都是以基于这些基本的坐标进行区分的。

  • groupId定义了项目属于哪一个组,这个组每每和项目所在的组织或公司存在关联,譬如你在googlecode上创建了一个名为myapp的项目,那么groupId就应该是com.googlecode.myapp,若是你的公司是mycom,有一个项目为myapp,那么groupId就应该是com.mycom.myapp。本书中全部的代码都基于groupId com.juvenxu.mvnbook。

  • artifactId定义了当前Maven项目在组中惟一的ID,咱们为这个Hello World项目定义artifactId为hello-world,本书其余章节代码会被分配其余的artifactId。而在前面的groupId为com.googlecode.myapp的例子中,你可能会为不一样的子项目(模块)分配artifactId,如:myapp-util、myapp-domain、myapp-web等等。

  • version指定了Hello World项目当前的版本——1.0-SNAPSHOT。SNAPSHOT意为快照,说明该项目还处于开发中,是不稳定的版本。随着项目的发展,version会不断更新,如升级为1.0、1.1-SNAPSHOT、1.一、2.0等等。

  • 最后一个name元素声明了一个对于用户更为友好的项目名称,虽然这不是必须的,但我仍是推荐为每一个POM声明name,以方便信息交流。 没有任何实际的Java代码,咱们就可以定义一个Maven项目的POM,这体现了Maven的一大优势,它能让项目对象模型最大程度地与实际代码相独立,咱们能够称之为解耦,或者正交性,这在很大程度上避免了Java代码和POM代码的相互影响。好比当项目须要升级版本时,只须要修改POM,而不须要更改Java代码;而在POM稳定以后,平常的Java代码开发工做基本不涉及POM的修改。

Main

项目主代码和测试代码不一样,项目的主代码会被打包到最终的构件中(好比jar),而测试代码只在运行测试时用到,不会被打包。默认状况下,Maven假设项目主代码位于src/main/java目录,咱们遵循Maven的约定,建立该目录,而后在该目录下建立文件com/juvenxu/mvnbook/helloworld/HelloWorld.java,其内容以下:

package com.juvenxu.mvnbook.helloworld;

public class HelloWorld
{
    public String sayHello()
    {
        return "Hello Maven";
    }

    public static void main(String[] args)
    {
        System.out.print( new HelloWorld().sayHello() );
    }
}

关于该Java代码有两点须要注意。首先,在95%以上的状况下,咱们应该把项目主代码放到src/main/java/目录下(遵循Maven的约定),而无须额外的配置,Maven会自动搜寻该目录找到项目主代码。其次,该Java类的包名是com.juvenxu.mvnbook.helloworld,这与咱们以前在POM中定义的groupId和artifactId相吻合。通常来讲,项目中Java类的包都应该基于项目的groupId和artifactId,这样更加清晰,更加符合逻辑,也方便搜索构件或者Java类。 代码编写完毕后,咱们使用Maven进行编译,在项目根目录下运行命令 mvn clean compile 便可。

clean告诉Maven清理输出目录target/,compile告诉Maven编译项目主代码,从输出中咱们看到Maven首先执行了clean:clean任务,删除target/目录,默认状况下Maven构建的全部输出都在target/目录中;接着执行resources:resources任务(未定义项目资源,暂且略过);最后执行compiler:compile任务,将项目主代码编译至target/classes目录(编译好的类为com/juvenxu/mvnbook/helloworld/HelloWorld.Class)。

Configuration

Network

Proxy

编辑~/.m2/settings.xml文件(若是没有该文件,则复制$M2HOME/conf/settings.xml)。添加代理配置以下:

<settings>
  ...
<pqroxies>
  <proxy>
    <id>my-proxy</id>
    <active>true</active>
    <protocol>http</protocol>
    <host>代理服务器主机名</host>
    <port>端口号</port>
    <!--
        <username>***</username>
        <password>***</password>
        <nonProxyHosts>repository.mycom.com|*.google.com</nonProxyHosts>
-->
  </proxy>
  </proxies>
  ...
</settings>

Mirror

众所周知的缘由,国内有时候并不可以很顺畅的访问Maven的中央仓库,每每咱们须要访问国内的镜像地址:

  • OSChina Maven教程

<mirror>
<id>CN</id>
<name>OSChina Central</name> 
<url>http://maven.oschina.net/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>

Error List

网络问题

(1)有时候由于众所周知的网络问题,致使Maven没法访问中央仓库而后扔出一大堆错误,这个时候能够尝试参考上文中的设置代理。可是也要注意,是否是有一些私库中的Repository。

编译问题

(1)有时候执行mvn compile时候会爆出没法找到junit的错误,可能的解决方法有:

  • 在Eclipse的Projects选项中使用Projects Clean

  • 在pom.xml中引入junit依赖项,而且保证其scope为compile:

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>

(2)有时候在Eclipse下执行mvn compile或者相关命令时,会报某某文件出现不识别字符或者非UTF-8编码,此时能够作几步检查:

  • 检查对应的Java文件是否有Bom头

  • 检查对应的Java文件的编码

  • 若是都没有问题,在Eclipse中先将文件编码设置为GBK,再改回UTF-8试试。

Reference

相关文章
相关标签/搜索