入门
1.常用命令
- mvn -Dmaven.test.skip=true package ##跳过测试
- mvn clean && mvn -Dmaven.test.skip=true package ##跳过测试
- mvn buildnumber:create ##单独执行buildnumber
- mvn appassembler:assemble ##单独执行appassembler
- mvn -Dtimestamp=1234 assembly:single ##单独执行打包
- mvn process-sources ##是先执行依赖,在执行定义process-sources的replacer
- mvn replacer:replace ##只执行自己
- mvn appassembler:generate-daemons -X #
调试命令
可以看到
- maven自身的配置是用哪个文件
- maven执行所用的有效配置,包括xml和解析后的有效配置,
这个很重要,便于简化配置和进行理解
2.变量
- Project Model Variables
- 任何一个元素值都可以作为一个变量,如 project.artifactId, {project.build.sourceDirectory}
- 所有元素都是以”project.”为前缀
特殊变量
- project.basedir或者project.baseUri
- maven.build.timestamp 构建时间戳
- 这个3.2版本改为UTC时区,并且不能自定义;是因一个人提的需求所改,然后其它人又提了相反需求,蠢不蠢?
- 可以使用buildnumber定义${timestamp}字段,来代替这个字段使用
另外可参考官方入门介绍
Maven插件与生命周期
1.关系图解与执行样例
Maven常用插件与生命周期解析,如下图所示
- 区别:mvn process-sources 是先执行依赖;mvn replacer:replace只执行自己
- Maven defines 3 lifecycles in META-INF/plexus/components.xml:
- site和clean只能绑定自己的插件;default类型定义在META-INF/plexus/default-bindings.xml
执行样例,如下:
/Users/lcz/git/lingxi-ml>mvn -Dmaven.test.skip=true package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building lingxi-ml 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- buildnumber-maven-plugin:1.3:create (default) @ lingxi-ml ---
[INFO] Executing: /bin/sh -c cd /Users/lcz/git/lingxi-ml && git rev-parse --verify HEAD
[INFO] Working directory: /Users/lcz/git/lingxi-ml
[INFO] Storing buildNumber: 779e2920615e67c5fb5acb9da95ed253b6e0e838 at timestamp: 20150616100702
[INFO] Storing buildScmBranch: master
[INFO]
[INFO] --- maven-replacer-plugin:1.4.0:replace (default) @ lingxi-ml ---
[INFO] Replacement run on 1 file.
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ lingxi-ml ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 2 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ lingxi-ml ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 24 source files to /Users/lcz/git/lingxi-ml/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ lingxi-ml ---
[INFO] Not copying test resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ lingxi-ml ---
[INFO] Not compiling test sources
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ lingxi-ml ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ lingxi-ml ---
[INFO] Building jar: /Users/lcz/git/lingxi-ml/target/lingxi-ml-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- appassembler-maven-plugin:1.10:assemble (generate-jsw) @ lingxi-ml ---
[INFO] Installing artifact /Users/lcz/.m2/repository/org/ansj/ansj_seg/1.3/ansj_seg-1.3.jar to /Users/lcz/git/lingxi-ml/target/appassembler/lib/ansj_seg-1.3.jar
[INFO] Installing artifact /Users/lcz/.m2/repository/org/ansj/tree_split/1.2/tree_split-1.2.jar to /Users/lcz/git/lingxi-ml/target/appassembler/lib/tree_split-1.2.jar
[INFO] Installing artifact /Users/lcz/.m2/repository/org/ansj/ansj_lucene4_plug/1.3/ansj_lucene4_plug-1.3.jar to /Users/lcz/git/lingxi-ml/target/appassembler/lib/ansj_lucene4_plug-1.3.jar
[INFO] Installing artifact /Users/lcz/.m2/repository/org/java-websocket/Java-WebSocket/1.3.0/Java-WebSocket-1.3.0.jar to /Users/lcz/git/lingxi-ml/target/appassembler/lib/Java-WebSocket-1.3.0.jar
[INFO] Installing artifact /Users/lcz/.m2/repository/com/alibaba/fastjson/1.2.6/fastjson-1.2.6.jar to /Users/lcz/git/lingxi-ml/target/appassembler/lib/fastjson-1.2.6.jar
[INFO] Installing artifact /Users/lcz/.m2/repository/org/json/json/20141113/json-20141113.jar to /Users/lcz/git/lingxi-ml/target/appassembler/lib/json-20141113.jar
[INFO] Installing artifact /Users/lcz/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar to /Users/lcz/git/lingxi-ml/target/appassembler/lib/log4j-1.2.17.jar
[INFO] Installing artifact /Users/lcz/.m2/repository/org/slf4j/slf4j-api/1.7.12/slf4j-api-1.7.12.jar to /Users/lcz/git/lingxi-ml/target/appassembler/lib/slf4j-api-1.7.12.jar
[INFO] Installing artifact /Users/lcz/.m2/repository/org/slf4j/jul-to-slf4j/1.7.12/jul-to-slf4j-1.7.12.jar to /Users/lcz/git/lingxi-ml/target/appassembler/lib/jul-to-slf4j-1.7.12.jar
[INFO] Installing artifact /Users/lcz/.m2/repository/org/slf4j/jcl-over-slf4j/1.7.12/jcl-over-slf4j-1.7.12.jar to /Users/lcz/git/lingxi-ml/target/appassembler/lib/jcl-over-slf4j-1.7.12.jar
[INFO] Installing artifact /Users/lcz/.m2/repository/org/slf4j/slf4j-log4j12/1.7.12/slf4j-log4j12-1.7.12.jar to /Users/lcz/git/lingxi-ml/target/appassembler/lib/slf4j-log4j12-1.7.12.jar
[INFO] Installing artifact /Users/lcz/git/lingxi-ml/target/lingxi-ml-0.0.1-SNAPSHOT.jar to /Users/lcz/git/lingxi-ml/target/appassembler/lib/lingxi-ml-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- maven-assembly-plugin:2.2-beta-5:single (make-assembly) @ lingxi-ml ---
[INFO] Reading assembly descriptor: src/main/assembly/assembly.xml
[INFO] Building tar : /Users/lcz/git/lingxi-ml/target/lingxi-ml-0.0.1-SNAPSHOT-20150616100702-linux.tar.gz
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.596 s
[INFO] Finished at: 2015-06-16T10:07:08+08:00
[INFO] Final Memory: 21M/295M
[INFO] ------------------------------------------------------------------------
2.各插件介绍
- maven-compiler-plugin:编译插件,定义jvm版本号和编码等
- maven-jar-plugin:打jar包插件
- maven-assembly-plugin打发布包插件
- 与appassembler-maven-plugin的区别,前者是打包为.gz或.tar;后者是构建跨平台脚本或者进行jsw封装
- appassembler-maven-plugin 自动生成跨平台的启动脚本,省去了手工写脚本的麻烦,而且还可以生成jsw(Java Service Wrapper)的后台运行程序
- All dependencies and the artifact of the project itself are placed in a generated Maven repository in a defined assemble directory。所以依赖和工程自己的文件都放到汇集目录
- All artifacts (dependencies + the artifact from the project) are added to the classpath in the generated bin scripts.所以依赖和工程自己的文件都会增加到classpath目录
- JSW介绍
- Run a Java application as a Windows Service or UNIX Daemon
- Java Application Reliability异常宕机后可以重启
- Out of the Box 脚本
- Flexible Configuration 可以通过conf/wrapper.conf 调整JVM参数
- The Wrapper makes sure that all console output is logged 控制台日志也会记录
- maven-eclipse-plugin:eclipse插件,修改.settings/org.eclipse.core.resources.prefs文件.可以不用配置,我的工程没有加这个插件,也没有影响
- maven-replacer-plugin:替换插件,比如有一个版本描述文件,每次打包后,把与版本描述相关变量替换掉
- buildnumber-maven-plugin:生成一个不重复的序列号,如时间戳等,做版本标识,详细可参考官方文档:
- 属性format,定义${buildnumber}变量格式,如{1}或者{0,date,yyyyMMdd}-{1}
- items 固定写死”scmVersion”, “timestamp”
- 属性timestampFormat,定义timestamp的格式.
- timestampPropertyName默认是${timestamp},可以命名时间戳为另一个属性名字,
这样就有两个变量可以让整个工程使用,分别是${buildnumber}和${timestamp}
- providerImplementations定义SCM方式,如cvs\svn,默认是git。
- build-helper-maven-plugin:增加add-source,如果命名标准,则不需要这个插件
用到插件 - maven-source-plugin:源码插件,发布时自动将源码同时发布的配置
2.1.appassembler
Writing good end to end portable applications in Java has always been a pain because of the missing OS abstractions,appassembler的目的就是通过应用描述解决这个问题
2.1.1.appassembler:assemble
- appassembler:assemble,下面是关键参数,详细可参考官方文档
- assembleDirectory 目标目录,默认${project.build.directory}/appassembler
- binFileExtensions 通过.sh定义
- configurationSourceDirectory默认是src/main/config,从这个目录拷贝到configurationDirectory目录.
这个拷贝不重要,可以交给assemble去做,但是configurationDirectory还是要配置的,是为了创建脚本时正确应用
- repositoryLayout支持类型,”default” (Maven2) | “legacy” (Maven1) | “flat” (flat lib/ style) ,一般选择flat模式,以jar包方式放在lib目录下
- assembleDirectory 默认${project.build.directory}/appassembler;
- repositoryName默认repo,所以就是最终目录为./target/appassembler/repo,为了便于理解,与flat模式的lib常识匹配,对应修改repositoryName配置为lib
- useWildcardClassPath 如果依赖非常多,可以在classpath中配置为REPO/*,注意要与flat模式配合使用
- platforms 生成对应的二进制文件”all”(default/empty) | “windows” | “unix”.
2.1.2.appassembler:create-repository
appassembler:create-repository 说是要代替assembly的,可以忽略
2.1.3.appassembler:generate-daemons
appassembler:generate-daemons Generates JSW based daemon wrappers.
主要配置说明,详细可参考官方文档
- daemons 要配置的daemon集合
- target 要生成daemon的目标目录,默认${project.build.directory}/generated-resources/appassembler.
- 其它配置与assemble类似,但要注意下面两点
- includeConfigurationDirectoryInClasspath这个参数assemble有,generate-daemons没有,所以要通过deamon中的configuration.directory.in.classpath.first设置,而且
值与configurationDirectory配置一样,这个地方感觉设计不合理
- 外层的repositoryName与deamon中的set.default.REPO_DIR修改的是同一个参数
- includeConfigurationDirectoryInClasspath这个参数assemble有,generate-daemons没有,所以要通过deamon中的configuration.directory.in.classpath.first设置,而且
Daemon Scripts
The following configuration will generate a daemon daemon-1 and daemon-1.bat script within the ${project.build.directory}/generated-resources/appassembler/jsw/daemon-1/bin/ folder.
<daemons>
<daemon>
<id>daemon-1</id>
<mainClass>com.westerngeco.example.App</mainClass>
<platforms>
<platform>jsw</platform>
</platforms>
</daemon>
</daemons>
- Platforms
这些平台可用: - aix-ppc-32
- aix-ppc-64
- hpux-parisc-64
- linux-x86-32
- linux-x86-64
- linux-ppc-64
- macosx-ppc-32
- macosx-x86-universal-32
- macosx-universal-32
- macosx-universal-64
- solaris-sparc-32
- solaris-sparc-64
- solaris-x86-32
- windows-x86-32
- windows-x86-64
样例如下
<generatorConfigurations>
<generatorConfiguration>
<generator>jsw</generator>
<includes>
<include>linux-x86-32</include>
<include>linux-x86-64</include>
<include>windows-x86-32</include>
</includes>
</generatorConfiguration>
</generatorConfigurations>
<platforms>
<platform>jsw</platform>
</platforms>
- Daemon JVM Settings extraArgument中的参数不能带空格
<jvmSettings>
<!-- 启动内存配置 -->
<initialMemorySize>2048</initialMemorySize>
<maxMemorySize>2048</maxMemorySize>
<maxStackSize>128</maxStackSize>
<systemProperties>
<systemProperty>MYCAT_HOME=.</systemProperty>
</systemProperties>
<extraArguments>
<extraArgument>-server </extraArgument>
<extraArgument>-XX:MaxPermSize=64M</extraArgument>
<extraArgument>-XX:+AggressiveOpts</extraArgument>
<extraArgument>-XX:MaxDirectMemorySize=2G</extraArgument>
<!-- 远程JMX -->
<extraArgument>-Dcom.sun.management.jmxremote </extraArgument>
<extraArgument>-Dcom.sun.management.jmxremote.port=1984</extraArgument>
<extraArgument>-Dcom.sun.management.jmxremote.authenticate=false </extraArgument>
<extraArgument>-Dcom.sun.management.jmxremote.ssl=false </extraArgument>
</extraArguments>
</jvmSettings>
- aemon Wrapper Log,可以在wrapper.conf中配置,默认wrapper.logfile=../logs/wrapper.log
- Daemon Generator Configurations
generatorConfigurations通过覆盖wrapper.conf提供了一种满足需求的灵活性。
<generatorConfigurations>
<generatorConfiguration>
<generator>jsw</generator>
<includes>
<include>linux-x86-32</include>
<include>linux-x86-64</include>
</includes>
<configuration>
<property>
<name>configuration.directory.in.classpath.first</name>
<value>etc</value>
</property>
<property>
<name>set.default.REPO_DIR</name>
<value>lib</value>
</property>
<property>
<name>wrapper.logfile</name>
<value>logs/wrapper.log</value>
</property>
</configuration>
</generatorConfiguration>
</generatorConfigurations>
上面这个配置,对 set.default.REPO_DIR, wrapper.logfile or configuration.directory.in.classpath.first 几个参数进行了用户自定义。
2.1.4.assemble模式样例
下面是一个样例,生成.sh和.bat文件
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<configurationDirectory>conf</configurationDirectory>
<includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
<repositoryLayout>flat</repositoryLayout>
<repositoryName>lib</repositoryName>
<useWildcardClassPath>true</useWildcardClassPath>
<binFileExtensions>
<unix>.sh</unix>
</binFileExtensions>
<extraJvmArguments>-Xmx2g -Xms256m</extraJvmArguments>
<programs>
<program>
<mainClass>main.SocketCenter</mainClass>
<id>lingxi-ml</id>
</program>
</programs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
对应的src/main/assembly/assembly.xml文件是:
需要拷贝的源文件目录是${project.build.directory}/appassembler
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>${timestamp}</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>tar.gz</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}/appassembler/lib</directory>
<outputDirectory>${project.artifactId}/lib</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/appassembler/bin</directory>
<outputDirectory>${project.artifactId}/bin</outputDirectory>
</fileSet>
<fileSet>
<directory>src/main/resources</directory>
<outputDirectory>${project.artifactId}/conf</outputDirectory>
</fileSet>
<fileSet>
<directory>data</directory>
<outputDirectory>${project.artifactId}/data</outputDirectory>
</fileSet>
<fileSet>
<directory>src/main/assembly/bin</directory>
<outputDirectory>${project.artifactId}/bin</outputDirectory>
<fileMode>0755</fileMode>
<includes>
<include>*.sh</include>
</includes>
</fileSet>
<fileSet>
<directory>${basedir}</directory>
<outputDirectory>${project.artifactId}</outputDirectory>
<includes>
<include>version.txt</include>
</includes>
</fileSet>
</fileSets>
</assembly>
2.1.5.deamon样例
生成jsw的deamon,并且对应的assembly
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<configurationDirectory>conf</configurationDirectory>
<repositoryLayout>flat</repositoryLayout>
<repositoryName>lib</repositoryName>
<useWildcardClassPath>true</useWildcardClassPath>
<daemons>
<daemon>
<mainClass>main.SocketCenter</mainClass>
<id>${project.artifactId}</id>
<commandLineArguments>
<commandLineArgument>start</commandLineArgument>
</commandLineArguments>
<platforms>
<platform>jsw</platform>
</platforms>
<jvmSettings>
<systemProperties>
<systemProperty>ML_HOME=.</systemProperty>
</systemProperties>
<extraArguments>
<extraArgument>-Xms256m</extraArgument>
<extraArgument>-Xmx2048m</extraArgument>
<extraArgument>-XX:+AggressiveOpts</extraArgument>
<!-- 远程JMX -->
<extraArgument>-Dcom.sun.management.jmxremote </extraArgument>
<extraArgument>-Dcom.sun.management.jmxremote.port=1984</extraArgument>
<extraArgument>-Dcom.sun.management.jmxremote.authenticate=false </extraArgument>
<extraArgument>-Dcom.sun.management.jmxremote.ssl=false </extraArgument>
</extraArguments>
</jvmSettings>
<generatorConfigurations>
<generatorConfiguration>
<generator>jsw</generator>
<includes>
<include>linux-x86-64</include>
<include>windows-x86-64</include>
<include>macosx-universal-64</include>
</includes>
<configuration>
<property>
<name>configuration.directory.in.classpath.first</name>
<value>conf</value>
</property>
<property>
<name>wrapper.logfile</name>
<value>./logs/wrapper.log</value>
</property>
</configuration>
</generatorConfiguration>
</generatorConfigurations>
</daemon>
</daemons>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>generate-daemons</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly-jsw.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
对应的src/main/assembly/assembly-jsw.xml文件是:
需要拷贝的源文件目录是
project.build.directory/generated−resources/appassembler/jsw/
{project.artifactId}
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>${timestamp}</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>tar.gz</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}/generated-resources/appassembler/jsw/${project.artifactId}/lib</directory>
<outputDirectory>${project.artifactId}/lib</outputDirectory>
<includes>
<include>*.jar</include>
<include>*wrapper*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/generated-resources/appassembler/jsw/${project.artifactId}/bin</directory>
<outputDirectory>${project.artifactId}/bin</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>${project.build.directory}/generated-resources/appassembler/jsw/${project.artifactId}/conf</directory>
<outputDirectory>${project.artifactId}/conf</outputDirectory>
</fileSet>
<fileSet>
<directory>src/main/resources</directory>
<outputDirectory>${project.artifactId}/conf</outputDirectory>
</fileSet>
<fileSet>
<directory>data</directory>
<outputDirectory>${project.artifactId}/data</outputDirectory>
</fileSet>
<fileSet>
<directory>src/main/assembly/bin</directory>
<outputDirectory>${project.artifactId}/bin</outputDirectory>
<fileMode>0755</fileMode>
<includes>
<include>*.sh</include>
</includes>
</fileSet>
<fileSet>
<directory>${basedir}</directory>
<outputDirectory>${project.artifactId}</outputDirectory>
<includes>
<include>version.txt</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/resources</directory><!-- 仅为了创建logs目录 -->
<outputDirectory>${project.artifactId}/logs</outputDirectory>
<excludes>
<exclude>**/*</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
3.插件管理
官方Project Plugin Management,可以查找各插件的最新版本