Apache Maven是软件(主要针对java)项目管理及自动构建工具,由Apache软件基金会所提供。Maven是主要用于Java项目的构建。maven在犹太语中“蓄电池知识”, Maven描述了如何构建软件并处理了依赖:基于项目对象模型(POM)。
Maven也可被用于构建和管理各种项目,例如C#,Ruby,Scala和其他语言编写的项目。Maven曾是Jakarta项目的子项目,现为由Apache软件基金会主持的独立Apache项目。
源码下载:https://github.com/bava/gswm-book
作者邮件: [email protected] or [email protected].
Maven的优点
标准的目录结构
依赖管理
插件
统一的构建抽象
工具支持:IDE和持续集成系统等。
Archetype(类似模板)
开源(Sonatype公司提供商业支持)
Maven的设计理念:CoC(Convention over configuration或coding by convention)
Maven类似产品:
Ant + Ivyt (http://ant.apache.org) 使用配置文件 build.xml。
<project name="Sample Build File" default="compile" basedir="."> <target name="compile" description="Compile Source Code"> <echo message="Starting Code Compilation"/> <javac srcdir="src" destdir="dist"/> <echo message="Completed Code Compilation"/> </target> </project>
Ant很灵活,因为容易搞得复杂。Apache Ivy (http://ant.apache.org/ivy/)为Ant提供了增强的自动依赖管理。ivy.xml实例:
<ivy-module version="2.0"> <info organisation="com.apress" module="gswm-ivy" /> <dependencies> <dependency org="org.apache.logging.log4j" name="log4j-api" rev="2.0.2" /> </dependencies> </ivy-module>
Gradle (http://gradle.org/),使用Groovy-based Domain Specific Language (DSL)。综合了Ant的灵活性和maven的约定及依赖管理。为目前最火爆的java编译工具,但容易导致复杂的构建。 build.gradle实例:
apply plugin: 'java' version = '1.0' repositories { mavenCentral() } dependencies { testCompile group: 'junit', name: 'junit', version: '4.10' }
当前版本为Maven 3.3.3, 要求JDK 1.7或以上版本。下载地址:http://maven.apache.org/download.cgi。
Linux下面下载之后解压到/var/lib/apache-maven-3.3.3,并把/var/lib/apache-maven-3.3.3/bin加入PATH即可。
检验安装:
# mvn -v Apache Maven 3.3.3 (7994120775791599e205a5524ec3e0dfe41d4a06; 2015-04-22T19:57:37+08:00) Maven home: /var/lib/apache-maven-3.3.3 Java version: 1.7.0_79, vendor: Oracle Corporation Java home: /usr/java/jdk1.7.0_79/jre Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "2.6.32-573.el6.x86_64", arch: "amd64", family: "unix"
帮助:
# mvn -h usage: mvn [options] [<goal(s)>] [<phase(s)>] Options: -am,--also-make If project list is specified, also build projects required by the list -amd,--also-make-dependents If project list is specified, also build projects that depend on projects on the list -B,--batch-mode Run in non-interactive (batch) mode -b,--builder <arg> The id of the build strategy to use. -C,--strict-checksums Fail the build if checksums don't match -c,--lax-checksums Warn if checksums don't match -cpu,--check-plugin-updates Ineffective, only kept for backward compatibility -D,--define <arg> Define a system property -e,--errors Produce execution error messages -emp,--encrypt-master-password <arg> Encrypt master security password -ep,--encrypt-password <arg> Encrypt server password -f,--file <arg> Force the use of an alternate POM file (or directory with pom.xml). -fae,--fail-at-end Only fail the build afterwards; allow all non-impacted builds to continue -ff,--fail-fast Stop at first failure in reactorized builds -fn,--fail-never NEVER fail the build, regardless of project result -gs,--global-settings <arg> Alternate path for the global settings file -gt,--global-toolchains <arg> Alternate path for the global toolchains file -h,--help Display help information -l,--log-file <arg> Log file to where all build output will go. -llr,--legacy-local-repository Use Maven 2 Legacy Local Repository behaviour, ie no use of _remote.repositories. Can also be activated by using -Dmaven.legacyLocalRepo=true -N,--non-recursive Do not recurse into sub-projects -npr,--no-plugin-registry Ineffective, only kept for backward compatibility -npu,--no-plugin-updates Ineffective, only kept for backward compatibility -nsu,--no-snapshot-updates Suppress SNAPSHOT updates -o,--offline Work offline -P,--activate-profiles <arg> Comma-delimited list of profiles to activate -pl,--projects <arg> Comma-delimited list of specified reactor projects to build instead of all projects. A project can be specified by [groupId]:artifactId or by its relative path. -q,--quiet Quiet output - only show errors -rf,--resume-from <arg> Resume reactor from specified project -s,--settings <arg> Alternate path for the user settings file -T,--threads <arg> Thread count, for instance 2.0C where C is core multiplied -t,--toolchains <arg> Alternate path for the user toolchains file -U,--update-snapshots Forces a check for missing releases and updated snapshots on remote repositories -up,--update-plugins Ineffective, only kept for backward compatibility -V,--show-version Display version information WITHOUT stopping build -v,--version Display version information -X,--debug Produce execution debug output
maven的配置文件一般位于用户目录的 .m2目录。全局设置存储在/var/lib/apache-maven-3.3.3/conf/。最重要的配置文件是settings.xml。
使用mvn -X可以看到相关的加载过程。默认的Settings.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"> <localRepository/> <interactiveMode/> <usePluginRegistry/> <offline/> <pluginGroups/> <servers/> <mirrors/> <proxies/> <profiles/> <activeProfiles/> </settings>
关于配置文件的详细介绍参见https://maven.apache.org/settings.html及https://maven.apache.org/guides/mini/guide-configuring-maven.html。
用pom.xml描述,Maven Central地址: repo.maven.apache.org 和 uk.maven.org. 默认的架构如下:
考虑到公司内部共享、安全、知识产权(不发布本公司的包)、授权、带宽和下载速度等,一般架构如下:
开源仓库管理器有:
Sonatype Nexus www.sonatype.com/nexus
Apache Archiva http://archiva.apache.org/
Artifactory www.jfrog.com/open-source/
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"> ....... <profiles> <profile> <id>your_company</id> <repositories> <repository> <id>spring_repo</id> <url>http://repo.spring.io/release/</url> </repository> <repository> <id>jboss_repo</id> <url>https://repository.jboss.org/</url> </repository> </repositories> </profile> </profiles> <activeProfiles> <activeProfile>your_company</activeProfile> </activeProfiles> ....... </settings>
仓库添加在 pom.xml 中可移植性好,settings.xml一般用来存放企业级别的设置。
依赖通常是JAR, WAR, enterprise archive (EAR)和ZIP. 字段如下:
groupId: 如 org.hibernate.log4j和org.springframework.boot。
artifactId: 如 log4j。
version: 版本,如1.0.0, 2.3.1-SNAPSHOT和4.3.6.Final。
type: 如JAR, WAR和EAR.
Maven支持传递依赖,碰到版本冲突时,深度优先,如果同一深度,则先碰到的优先。注意尽量不要有版本冲突。
依赖的范围有:
compile(默认, build, test和run可见)
provided: build、test可见,比如 Servlet api, JSP api。
runtime: run可见
test: test可见
system: 类似 provided,但是不从仓库获取,写死到文件系统。
import: 适用.pom文件,Maven 2.0.9及以后版本支持。
还可以手工加载,比如:
# mvn install:install-file -DgroupId=com.apress.gswmbook -DartifactId=test -Dversion=1.0.0 -Dfile=/root/gswm-book/chapter3/test.jar -Dpackaging=jar -DgeneratePom=true [WARNING] [WARNING] Some problems were encountered while building the effective settings [WARNING] Unrecognised tag: 'server' (position: START_TAG seen ...<!-- 115.236.185.202\u6d4b\u8bd5\u73af\u5883 -->\n\t<server>... @142:10) @ /var/lib/apache-maven-3.3.3/conf/settings.xml, line 142, column 10 [WARNING] [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Stub Project (No POM) 1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-install-plugin:2.4:install-file (default-cli) @ standalone-pom --- [INFO] Installing /root/gswm-book/chapter3/test.jar to /Repository/com/apress/gswmbook/test/1.0.0/test-1.0.0.jar [INFO] Installing /tmp/mvninstall7757910186748006943.pom to /Repository/com/apress/gswmbook/test/1.0.0/test-1.0.0.pom [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.285 s [INFO] Finished at: 2015-11-18T17:20:37+08:00 [INFO] Final Memory: 6M/118M [INFO] ------------------------------------------------------------------------ [root@localhost chapter3]#
常用的目录有src/main/resources、src/main/scripts、src/test/resources、src/main/webapp、src/it、src/main/db、src/site。
新建HelloWorld类:
public class HelloWorld { public void sayHello() { System.out.print("Hello World"); } }
新建HelloWorldTest类:
import java.io.ByteArrayOutputStream; import java.io.PrintStream; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.io.IOException; /** Updated the test so that it is more platform independent */ public class HelloWorldTest { private final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); @Before public void setUp() { System.setOut(new PrintStream(outStream)); } @Test public void testSayHello2() throws IOException { HelloWorld hw = new HelloWorld(); hw.sayHello(); outStream.flush(); String printedOutPut = new String(outStream.toByteArray()); String[] outputData = printedOutPut.split(System.getProperty("line.separator")); Assert.assertEquals("Hello World", outputData[0]); } @After public void cleanUp(){ System.setOut(null); } }
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.apress.gswmbook</groupId> <artifactId>gswm</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging> <name>Getting Started with Maven</name> <url>http://apress.com</url> <properties> <junit.version>4.12</junit.version> </properties> <developers> <developer> <id>balaji</id> <name>Balaji Varanasi</name> <email>[email protected]</email> <properties> <active>true</active> </properties> </developer> <developer> <id>sudha</id> <name>Sudha Belida</name> <email>[email protected]</email> <properties> <active>true</active> </properties> </developer> </developers> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> <exclusions> <exclusion> <groupId> org.hamcrest</groupId> <artifactId>hamcrest</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
注意上面有junit支持,并禁止org.hamcrest的传递依赖,执行'mvn dependency:tree", 再“mvn package“,即可编译成功。
执行mvn compiler:compile
上面的 compiler 就是插件,compile是目标。
类似的有mvn clean:clean,mvn plugin_identifier:goal_identifier
插件可以在pom.xml中配置,比如强行用java6编译:
<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> <!-- Project details omitted for brevity --> <dependencies> <!-- Dependency details omitted for brevity --> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> </project>
<build /> 有个非常有用的子tag: finalName.默认为<<project_artifiact_id>>-<<project_version>> 。
maven的生命周期如下:
Default: 编译、打包、部署
Clean: 清理
Site: 生成文档和site
阶段:
Validate: 运行检查确保该项目是正确的,所有依赖下载并可用。
Compile:编译源代码。
Test:使用框架运行单元测试。这一步不要求应用程序打包。
Package:打包代码为发布格式,如JAR或WAR。
Install:安装包到本地仓库。
Deploy: 推安装包到远程仓库。
<packaging>jar</packaging>会自动指定目标。
通常测试失败,打包也会失败,可以通过mvn package –Dmaven.test.skip=true 不执行测试阶段。
python测试开发精华群 291184506 PythonJava单元白盒测试 144081101