Maven

Maven是和Ant同一角色的工具,功能更加强大,现已是主流项目管理工具。使用仓库管理jar包并解决Jar包间依赖关系,并有编译、测试、打包、发布等功能。

1. 基本使用

安装

Maven需要java运行环境,所以安装之前需要先安装Java并配置好JAVA_HOME变量。然后到Maven官方下载页面下载到maven压缩包apache-maven-3.3.3-bin.zip,maven是跨平台绿色(Portable)软件,因此解压至随便某一文件夹即可。然后配置系统PATH变量,指向解压maven目录/bin目录。

验证安装是否成功:在命令行下输入mvn -version,如果出现版本信息,表示安装成功了。这里有个小诀窍,通过mvn查版本这个命令,也可以查看jdk的位置。

基本概念

构建(build)包括了编译、运行单元测试、生成文档、打包和部署等工作。

构件(artifact)是maven的项目单元,groupId是开发的组织单元。一个项目可以由groupId、artifactId和版本version唯一标识确定。一般而言,groupId常用域名来命名,以保证全球唯一性。

可用镜像

maven官方网站在国内访问非常非常慢,现在国内阿里云镜像速度还挺不错,编辑一下~/.m2/settings.xml

  <mirrors>
    <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>        
    </mirror>
  </mirrors>

网络代理问题

如果你所在的网络需要通过代理链接互联网,那麽在执行mvn的时候加上设置:

mvn -DproxySet=true -DproxyHost=proxy.myproxy.com -DproxyPort=8080 --help

或者编辑一下~/.m2/settings.xml(如果该文件不存在,则复制maven/conf/settings.xml一份):

<?xml version="1.0" encoding="UTF-8"?>
<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">
      <proxies>
         <proxy>
            <id>my-proxy</id>
            <active>true</active>
            <protocol>http</protocol>
            <host>proxy.host.net</host>
            <port>8080</port>
            <!--<username>proxyuser</username>
            <password>proxypass</password>
            <nonProxyHosts>local.net|some.host.com</nonProxyHosts>-->
            </proxy>
      </proxies>
</settings>

maven常用命令

在有pom.xml文件的文件夹目录下,命令行执行:

mvn compile #编译maven项目
mvn test-compile #编译项目测试代码
mvn test #运行应用程序中的单元测试
mvn site #生成项目相关信息的网站
mvn clean #清除目标目录中的生成结果
mvn package #打包maven项目,生成jar文件
mvn source:jar #生成源码包
mvn install #在本地 Repository 中安装 jar
mvn deploy #将打包的输出安装到远程仓库
mvn assembly:assembly #分发maven项目

mvn dependency:sources -DdownloadSources=true -DdownloadJavadocs=true # 要求maven下载jar包的源码和文档,开发时非常有用

跳过maven测试

默认情况下,mvn package会自动执行test下的测试。如果不希望maven执行测试,可以在mvn命令上加上-DskipTests-Dmaven.test.skip。这两者有时候有的会没效果,换另外一个试试。两者之中,前者会编译test代码并不会执行;后者则连test代码都不会编译。

关于项目jar包依赖

如果当前jar工具库依赖于A,编译后又不想其它项目使用jar工具库时引入依赖A。一般有两种配置方法:

1) 修改scope属性为provided:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>3.2.14.RELEASE</version>
        <scope>provided</scope>
    </dependency>

2) 修改optional为true:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>3.2.14.RELEASE</version>
        <optional>true</optional>
    </dependency>

这两者达到的效果是一样的,但是表达的语义还是有区别:

1)optional为true表达的是依赖的这个包在运行时是可以要也可以不要的。

2)provided表达的是依赖的这个包在运行时由外部的容器提供,项目本身不会带来这个jar包。

实际上,两者也是可以一起用的,也有这样的语义需求。

设置maven编码

如果不指定编码,将导致在不同的平台上编译时有不同的编码结果。

<project>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>
</project>

Maven工具

maven内置了一些实用的工具可以用来调试和检查maven项目:

mvn dependency:list #显示maven项目的依赖列表
mvn dependency:tree #显示maven项目的依赖列树
mvn dependency:analyze #依赖分析:
#依赖分析主要显示了:Used undeclared denpendencies 代码中有用到,但是没有显式声明的
#还有Unused declared dependencies 项目中未使用到的

如果有用eclipse打开maven项目,非常推荐打开pom.xml文件,eclipse中的Dependency Hierarchy功能,可以查看到最详细的maven依赖,对于找出冲突包有很大的帮助。

maven库本地存放位置

下载后的包等文件放在个人文件夹下.m2/repository目录下,存放路径规则:groupId/artifactId/version/artifactId-version.jar。例如maven配置文件中的依赖:

<dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>3.8.1</version>
</dependency>

则对应的本地包文件路径爲:.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar

关于分发(Package)

像apache/tomcat,一个压缩包里面已经有各种依赖的jar包、本身程序的jar包,还有启动脚本、配置文件等,这样的整个包分发出去之后,别人直接就可以当作绿色软件一样使用了,这就叫分发Package。

一般包含目录:

bin/ 存放可执行脚本
lib/ 存放程序的jar包和依赖jar包

更多参考这里

配合maven直接运行java程序

执行了mvn compile之后,类会被编译到target/classes目录。执行mvn test-compile测试程序则被编译到target/test-classes中。要运行这些class,还需要指定好classpath。

执行mvn dependency:copy-dependencies会把所有依赖的jar包都拷贝到target/dependency目录下。

执行main类:(下面命令是linux下的,如果是windows,则把-cp后面的参数的冒号改成分号)

cd target/classes
java -cp ../classes/:../dependency/* com/A/ClassName 参数

执行测试程序main类:(下面命令是linux下的,如果是windows,则把-cp后面的参数的冒号改成分号)

cd target/test-classes
java -cp ../test-classes/:../classes/:../dependency/* com/A/ClassName 参数

生成源码打包插件

项目pom.xml文件的build/plugins节点下,增加下面的配置:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.2.1</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

MyBatis之类的拷贝Java目录下的xml文件

<build>节点下面加上:

        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*</include>
                </includes>
            </resource>
        </resources>

2. maven创建项目和目录结构

约定优于配置,这是maven的重要思想。使用mvn archetype:create创建Maven项目。例如:

创建标准的Java项目:

mvn archetype:generate -B \
    -DarchetypeCatalog=internal \
    -DarchetypeArtifactId=maven-archetype-quickstart \
    -Dversion=0.1-SNAPSHOT \
    -DgroupId=com.demo \
    -DartifactId=app #新建一个Java项目,项目文件夹是app

较新版的eclipse自带maven插件,可以直接导入Existing Maven Project,不需要再执行mvn eclipse:eclipse将maven项目转换成eclipse项目。

如用使用eclipse,可以不用记住这些命令,直接创建maven各类型项目。

如果想设置maven中使用jdk6版本,因为一些默认会使用1.5版本,同时指定utf8编码,那么加上这一段:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>utf8</encoding> <!-- 指定编码 -->
                </configuration>
            </plugin>
        </plugins>
    </build>

maven项目的目录结构标准如下:

  app
   |-src
   |---main
   |-----java #存放源码路,包名和groupId和artifactId吻合
   |-----resources # 存放配置文件等资源文件
   |---test
   |-----java # 存放配置文件等资源文件
   |-----resources # 存放测试资源文件
   |---target # maven输出的各种文件存放的地方,例如class/jar文件
   |-pom.xml

创建一个web-app项目:

mvn archetype:generate -DarchetypeCatalog=internal -DgroupId=com.demo -DartifactId=web-app -Dversion=0.1-SNAPSHOT -DarchetypeArtifactId=maven-archetype-webapp #新建一个JAVA Web项目

目录结构:

web-app
   |-src
   |---main
   |-----resources
   |-----webapp
   |-------index.jsp
   |-------WEB-INF
   |---------web.xml
   |-pom.xml

添加servlet api maven依赖:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
</dependency>

更多操作参考这篇博客

子模块

参考这里

3. eclipse创建项目

新版的eclipse都已经带有maven插件了。使用eclipse创建maven项目的效果,等价于maven命令行创建项目之后再转换爲eclipse项目,因此,直接使用eclipse创建maven项目会方便一些。

创建java项目

eclipse菜单New-Maven Project,Archetype按默认的来,下一步输入Gourp Id和Artifact Id,完成。

创建java web项目

eclipse菜单New-Maven Project,Archetype选择maven-archetype-webapp,下一步输入Gourp Id和Artifact Id,完成。

此时如果eclipse编译失败,则需要添加servlet api maven依赖。

创建模块化的maven项目

首先创建一个标准的maven项目,然后双击pom.xml文件打开eclipse的pom编辑器,修改packing爲pom。然后右键点击项目,选择Maven-Update Project。然后就可以添加子module了,右键点击项目,选择Maven-New Maven Module Project新建子模块。

4. 配置私服

搭建自己的maven服务器非常适合于团队开发,除了加快访问maven官网的速度,还可以聚合maven仓库、发佈自己的私有jar包。常用的私服项目有:Nexus、Achiva、Artifactory等。下面使用nexus演示,本部分内容来自于《maven实战》。

首先从官网下载得到得到nexus-latest-bundle.zip文件,然后解压到任意一个目录,nexus是跨平台的,linux和windows均可。注意,太新的nexus不支持java1.6版本,试过2.4支持java1.6。

nexus的默认监听端口是8081,如果要修改,直接修改conf/nexus.properties文件,改成其他端口。

啓动:

./nexus start

配置使用该私服

nexus默认就创建了几个默认的仓库,最好用的就是聚合仓库public了,它是按照Releases、Snapshots、3rd party、Central的顺序来聚合的,前面3个都是nexus上存放的,如果找不到,再去中央仓库找。

修改本地.m2/settings.xml文件,修改mirrors部分爲下面内容:

  <mirrors>
    <mirror>
      <id>nexus</id>
      <mirrorOf>*</mirrorOf>
      <name>nexus server</name>
      <url>http://127.0.0.1:8081/nexus/content/groups/public</url>
    </mirror>
  </mirrors>

管理nexus私服

访问:http://127.0.0.1:8081/nexus/content/repositories/浏览nexus上面的所有maven仓库。

访问:http://127.0.0.1:8081/nexus/,然后使用默认用户名密码admin/admin123登录系统。常用功能有:

1)查看仓库列表,可以配置hosted类型的仓库,这种仓库的内容由nexus来保存。可以配置proxy类型的仓库,它只代理其他仓库。可以配置group聚合仓库,内容由多个有顺序的仓库聚合而成。

2)搜索、下载、上传jar包。

对于上传jar包的源码包到nexus上,只需要同时把test-0.0.2.jartest-0.0.2-sources.jar同时上传到nexus就可以了。

配置项目deploy到的仓库

指定deploy的配置只能写在项目的pom.xml文件中(和并列同级):

    <distributionManagement>
        <repository>
            <id>releases</id>
            <name>Nexus Release Repository</name>
            <url>http://11.11.11.11:8081/nexus/content/repositories/releases/</url>
        </repository>
        <snapshotRepository>
            <id>snapshots</id>
            <name>Nexus Snapshot Repository</name>
            <url>11.11.11.11:8081/nexus/content/repositories/snapshots/</url>
        </snapshotRepository>
    </distributionManagement>

同时.m2/settings.xml文件要配置:

    <server>
            <id>
                releases
            </id>
            <username>
                admin
            </username>
            <password>
                 admin123
            </password>
        </server>
        <server>
            <id>
                snapshots
            </id>
            <username>
                admin
            </username>
            <password>
                admin123
            </password>
        </server>

        <server>
            <id>
                thirdparty
            </id>
            <username>
                admin    
            </username>
            <password>
               admin123
            </password>
        </server>
  </servers>
  <!-- 还有一个profiles标签,不知道有没有用 -->

只deploy当前pom目录的项目

有时候例如我只想部署pom类型的maven,那么只需要加上-N

文档更新时间: 2018-11-12 16:52   作者:nick