Java构建工具 - Maven and Gradle

Maven

setting.xml

@ref https://maven.apache.org/settings.html
默认配置文件在~/.m2/settings.xml, 命令mvn -X可以查看正在使用哪个Setting.xml, 以及xml文件中的配置参数.
国内的mirrors和repositories基本都不可用, 所以直接使用central repositories(http://repo1.maven.org/maven2)并且设置proxy.

pom.xml

@ref https://maven.apache.org/pom.html

profiles

Create ypur maven projects

  • 命令: mvn archetype:generate -DgroupId=org.kshan.toolbox -DartifactId=XXX -Dversion=1.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-quickstart,
  • 如果创建web项目, 将最后一项参数修改为: -DarchetypeArtifactId=maven-archetype-webapp

命令

  1. mvn lifecycle, 比如mvn compile, mvn package, mvn install, 如果插件的目标绑定到该生命周期, 则会执行这个插件的目标(goal).
  2. mvn goal, 目标一般是由插件定义的, 例如mvn archetype:generate 就表示调用maven-archetype-plugin插件的generate目标,这种带冒号的调用方式与生命周期无关
    • 运行maven工程里的某个main方法: mvn exec:java -Dexec.mainClass="org.xx.className, 这里的goal是 maven-exec-plugin插件定义的.

lifecycle

  • mvn compile : compile the source code of the project
  • mvn test : test the compiled source code using a suitable unit testing framework
  • mvn package : take the compiled code and package it in its distributable format, such as a JAR.
    • -Dmaven.test.skip=ture :
    • -Dmaven.compile.fork=true : Runs the compiler in a separate process
    • -o : Work offline
  • mvn install : install the package into the local repository, for use as a dependency in other projects locally
  • mvn deploy: copies the final package to the remote repository
  • mvn clean : cleans up artifacts created by prior builds

snapshot快照库和release发布库的区别

maven中的仓库分为两种,snapshot快照仓库和release发布仓库。
snapshot快照仓库用于保存开发过程中的不稳定版本,release正式仓库则是用来保存稳定的发行版本。
定义一个组件/模块为快照版本,只需要在pom文件中在该模块的版本号后加上-SNAPSHOT即可(注意这里必须是大写),如下:

<groupId>com.abc</groupId>
<artifactId>myLib1</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>

插件的Goal

  • mvn eclipse:eclipse : 生成eclipse项目文件, 用于导入eclipse
  • mvn idea:idea : 同上
  • 将没有在maven官方repository中的jar包加入到本地的maven repository中: mvn install:install-file -Dfile=path-to-your-artifact-jar -DgroupId=your.groupId -DartifactId=your-artifactId -Dversion=your-version -Dpackaging=jar
  • 仅下载依赖: mvn dependency:resolve
  • 下载source和doc : mvn dependency:sources -DdownloadSources=true -DdownloadJavadocs=true
  • 运行指定Jar: mvn exec:java -Dexec.mainClass="com.vineetmanohar.module.Main" -Dexec.args="arg0 arg1 arg2"

插件(plugins)

<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
</plugin>
</plugins>
</pluginManagement>

maven-release-plugin

mvn clean
mvn release:prepare -Darguments="-DskipTests"
mvn release:perform

maven-resources-plugin

为了使项目结构更为清晰,Maven区别对待Java代码文件和资源文件,maven-compiler-plugin用来编译Java代码,maven-resources-plugin则用来处理资源文件。默认的主资源文件目录是src/main/resources,很多用户会需要添加额外的资源文件目录,这个时候就可以通过配置maven-resources-plugin来实现。此外,资源文件过滤也是Maven的一大特性,你可以在资源文件中使用${propertyName}形式的Maven属性,然后配置maven-resources-plugin开启对资源文件的过滤,之后就可以针对不同环境通过命令行或者Profile传入属性的值,以实现更为灵活的构建。

Jetty Plugin

  • mvn jetty:run
  • mvn -Djetty.port=8888 jetty:run

Help Plugin

  • 获取插件帮助: mvn help:describe -Dplugin=eclipse
  • 获取goal帮助: mvn help:describe -Dplugin=archetype
  • mvn help:active-profiles
  • mvn help:effective-settings
  • mvn help:system

依赖(dependencies)

<dependencies>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>${org.apache.thrift.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>

查看依赖

查看各个子module和引入Jar的依赖关系:

  • mvn dependency:list 可以看到当前项目已解析的依赖
  • mvn dependency:tree 看到依赖树
  • mvn dependency:analyse 查看依赖的工具

scope

scope有5个缺省值:

  • compile: 缺省值, 表示该maven项目在 编译 / 测试 / 运行 阶段都需要依赖这个jar包,
    • compile方式依赖的库具有传递性: 如果项目依赖了A库, 同时A依赖B(scope=compile) , 那么该项目也会依赖B;
    • compile方式依赖的库会被打包进项目Jar包的lib目录下;
  • provided: 表示该maven项目在 编译 / 测试 阶段都需要依赖这个jar包, 但在运行阶段是可以由容器(Container)来提供的, 而不必由该项目提供此Jar包;
    provided相当于compile, 是在打包阶段做了exclude的动作;
    • 例如一个Web应用, 在编译时可能需要 Servlet API来编译一个Servlet, 但是你不会想要在打包好的WAR中包含这个Servlet API, 这个Servlet API JAR 应该由应用服务器或者Servlet容器提供;
    • provided方式依赖的库并不是传递性的;
    • provided方式依赖的库也不会被打包进项目Jar包的lib目录下;
  • runtime: 在编译时不需要依赖此Jar包, 但在 运行 / 测试 的时候需要.
    例如JDBC驱动可以使用runtime, 因为只有在真正运行的时候才会调用到JDBC驱动的代码;
  • test: 表示该dependency的Jar包只在单元测试时会依赖到, 不会打包进项目, 不会在运行期被依赖到, 典型的比如junit;
  • system: 类似provided, 不会被打包进项目, 在编译时maven不会从默认的repository寻找Jar包, 而是从本地目录加载依赖的Jar包.
    使用system需要通过<systemPath>指定该依赖包在本地的路径;
  • import: Maven 2.0.9 之后新增;

FAQ