记录整理 maven 相关功能点。
maven 工程结构
path | desc |
---|---|
src/main/java |
Application/Library sources |
src/main/resources |
Application/Library resources |
src/main/filters |
Resource filter files |
src/main/webapp |
Web application sources |
src/test/java |
Test sources |
src/test/resources |
Test resources |
src/test/filters |
Test resource filter files |
src/it |
Integration Tests (primarily for plugins) |
src/assembly |
Assembly descriptors |
src/site |
Site |
LICENSE.txt |
Project’s license |
NOTICE.txt |
Notices and attributions required by libraries that the project depends on |
README.txt |
Project’s readme |
参考官网:
[2] introduction-to-the-standard-directory-layout
常用命令
语法: mvn [options] [<goal(s)>] [<phase(s)>]
创建项目: mvn archetype:generate -DgroupId=xx -DartifactId=xx -DarchetypeArtifactId=maven-archetype-quickstart
archetypeArtifactId 类型整理:
类型 | 说明 |
---|---|
maven-archetype-webapp |
webapp |
maven-archetype-quickstart |
java-app |
命令整理:
命令 | 说明 |
---|---|
mvn archetype:generate ... |
生成 maven 工程, 参考前文 |
mvn eclipse:eclipse |
转换成 eclipse 工程 |
mvn idea:idea |
转换成 idea 工程 |
mvn -h |
帮助 |
mvn --version |
查看版本 |
mvn test |
测试 |
mvn clean |
清空 |
mvn package |
打包 |
mvn package -DskipTests |
打包, 不执行测试用例, 会编译测试用例至 target/test-classes |
mvn package -Dmaven.test.skip=true |
打包, 不执行测试用例, 不编译测试用例 |
mvn clean package |
等价于先 mvn clean 再 mvn package |
mvn install |
打包到本地仓库 |
mvn dependency:sources |
下载源码包 |
mvn dependency:tree |
打印依赖 |
mvn dependency:tree -Dverbose -Dincludes=com.alibaba:fastjson |
打印依赖 |
mvn jetty:run |
需配置 jetty 插件 |
mvn package -f /root/yunka/pom.xml -am -pl user |
仅打包某个 module,指定 pom 路径 |
mvn -s /home/user/settings.xml clean compile |
指定 settings 文件 |
依赖原则
最短路径原则、声明优先原则
冲突解决
可以使用工具软件,比如InteliJ Idea 的插件 Maven Helper
,也可以使用命令 mvn dependency:tree -Dverbose -Dincludes=com.alibaba:fastjson
查看依赖详情然后手动配置 <exlude>
进行排除。
在JVM中,一个类型实例是通过它的全类名和加载它的类加载器(ClassLoader)实例来唯一确定的,通过不同的类加载器实例去加载需要隔离的类来实现的,这样即便两个全类名完全相同但内容不同的类,只要他们的类加载器实例不同,就能在一个容器进程中共存,并且各自运行互不干扰。
Java 在装载一个目录下所有jar包时, 它加载的顺序完全取决于操作系统,而Linux的顺序完全取决于INode的顺序,INode的顺序不完全能一致,所以上线多台机器使用同一个镜像,会有部分机器启动失败,因此最保底的方法就是把依赖排除;极为特殊的情况再考虑自定义 ClassLoader。
使用国内镜像仓库
修改 ~/.m2/setting.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">
<pluginGroups />
<proxies />
<servers />
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf><!-- 此处需注意,可设置为 * 强制走此镜像 -->
</mirror>
</mirrors>
<localRepository>D:/apache-maven-repository</localRepository>
</settings>
打包 executable jar
<!-- 开头部分的 -->
<packaging>jar</packaging><!-- 打包成jar -->
<name>qr_maker</name>
<dependencies>
<dependency>
</dependenciy>
</dependencies>
<!-- 配置打包begin -->
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId> maven-assembly-plugin </artifactId>
<version>2.6</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>cn.xz.qrmaker.view.MainWindow</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<!-- 配置打包end -->
配置 jetty
<build>
<finalName>xz</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.3.6.v20151106</version>
<configuration>
<httpConnector>
<port>80</port>
</httpConnector>
<scanIntervalSeconds>3</scanIntervalSeconds>
<webApp>
<contextPath>/xz</contextPath>
</webApp>
</configuration>
</plugin>
</plugins>
</build>
对应命令 mvn jetty:run -Djetty.port=8080
deploy到私服
不需要deploy到私服的module进行如下设置:
<!-- 增加属性 -->
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
</properties>
<!-- 或者在plugin节点设置如下 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
mvn versions:set -DnewVersion=1.0.1-RELEASE
mvn deploy -Dmaven.test.skip=true -Dversion=1.0.1-RELEASE
多模块版本控制
多个子模块的项目若使用自定义变量作为版本号,在构建时会显示如下 warning 信息:
[WARNING] 'version' contains an expression but should be a constant. @ com.mycompany:module:${myversion}, /home/pascal/Projects/maven-maven3-testcase/module/pom.xml
解决方式有两种:
1.只在父 pom 中定义一个版本号,在子 pom 中去掉 <version>xxx</version>
定义,采用继承机制;
2.参考官网:Maven CI Friendly Versions
使用 revision
关键字定义版本,parent pom 定义如下:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>18</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<name>First CI Friendly</name>
<version>${revision}</version>
...
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
<modules>
<module>child1</module>
..
</modules>
</project>
The child will look like this:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<version>${revision}</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-child</artifactId>
...
</project>