Maven 的使用
Maven 官方指南:https://maven.apache.org/guides/getting-started/index.html
Maven 环境配置
1.从官网下载 Maven
2.创建本地仓库地址
在 Maven 文件夹中,创建一个 repository 文件夹,用来当本地仓库。(推荐做法,非必须)
3.修改配置文件(conf/settings.xml)添加本地仓库地址
1
<localRepository>F:\apache-maven-3.8.4\repository</localRepository>
4.修改配置文件(conf/settings.xml)可添加多个远程仓库地址
1
2
3
4
5
6
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
5.配置环境变量
Windows PowerShell 终端:
1
2
3
4
5
6
7
# 设置 MAVEN_HOME 环境变量
[System.Environment]::SetEnvironmentVariable('MAVEN_HOME', 'F:\Java\apache-maven-3.8.4', [System.EnvironmentVariableTarget]::Machine)
# 将 %MAVEN_HOME%\bin 添加到 Path 环境变量
$oldPath = [System.Environment]::GetEnvironmentVariable('Path', [System.EnvironmentVariableTarget]::Machine)
$newPath = "$oldPath;%MAVEN_HOME%\bin"
[System.Environment]::SetEnvironmentVariable('Path', $newPath, [System.EnvironmentVariableTarget]::Machine)
Linux/Mac Command 终端:
1
2
3
echo 'export MAVEN_HOME=/path/to/apache-maven-3.8.4' >> ~/.zshrc
echo 'export PATH=$MAVEN_HOME/bin:$PATH' >> ~/.zshrc
source ~/.zshrc
6.最后,在 IDEA 中设置 Maven 主路径、配置文件及本地仓库地址即可
pom.xml 配置文件
POM 是指项目对象模型。 pom.xml 就是每个 maven 项目的配置文件,用以描述项目的各种信息。 pom.xml 基本文件结构如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<project>
<modelVersion></modelVersion> <!-- modelVersion 指定 pom.xml 符合哪个版本-->
<groupId></groupId> <!-- groupId 组织标识,定义了项目属于哪个组-->
<artifactId></artifactId> <!-- artifactId 工件id 项目名称,定义当前Maven项目在组中唯⼀的id-->
<version></version> <!-- version 当前项目的版本号-->
<!-- 一般 jar 包被识别为 groupId:artifactId:version 的形式。-->
<!-- 项目属性设置-->
<properties>
<project.build.sourceEncoding></project.build.sourceEncoding>
<maven.compiler.source></maven.compiler.source>
<maven.compiler.target></maven.compiler.target>
</properties>
<!-- 项目依赖管理-->
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<!-- 添加排除项,一般在依赖冲突的情况下添加-->
<exclusions>
<exclusion>
<groupId></groupId>
<artifactId></artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!-- 项目构建配置-->
<build>
<!-- 构建过程支持使用各类的插件完成构建-->
<plugins>
<plugin>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<configuration>
<source></source>
<target></target>
<compilerArgs></compilerArgs>
</configuration>
</plugin>
</plugins>
<!-- 在特定情况下,打包资源文件时使用,一般不用 -->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
项目的属性设置 <properties> … </properties> 标签中的内容,定义之后就可以直接使用 %{标签名}
来调用。
使用示例如下:
1
2
3
4
5
6
7
8
9
10
<properties>
<revision>1.0.0</revision> <!-- 用于自动化版本管理,结合 CI/CD 工具生成动态版本号 -->
<changelist>-SNAPSHOT</changelist> <!-- 用于区分开发版本和发布版本,生产环境留空,开发环境设置为-SNAPSHOT -->
</properties>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-artifact</artifactId>
<version>${revision}${changelist}</version>
</dependency>
Lifecycle 生命周期
clean
清空当前编译好的 class 文件validate
验证项目是否正确,并且所有必要信息都可用compile
将 java 编译成 class 文件(编译项目的源代码)test
使用合适的单元测试框架运行测试 , 测试代码不会被打包或部署(执行测试用例)package
将编译后的代码打包成可分发的格式,比如 jarverify
运行任何检查以验证包是否有效并符合质量标准install
将打包后的 jar 包放入本地仓库,供本地其他 maven 项目使用site
生成项目站点文档deploy
将 jar 包上传至中央仓库(将最终包复制到远程仓库,供其他开发人员和 maven 项目使用)
Plugins 插件
Maven 提供了很多且强大的插件。官网地址:https://maven.apache.org/plugins/index.html
Apache Maven Shade Plugin
使用 maven-shade-plugin 插件,对 maven 项目中包含的各种依赖打包成单个 jar 包程序(Uber-JAR)。
参考官方提供的使用案例:https://maven.apache.org/plugins/maven-shade-plugin/examples/executable-jar.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>shaded</shadedClassifierName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.example.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Apache Maven Assembly Plugin
maven-assembly-plugin 是一个更通用的打包插件,它可以创建多种格式的分发包,如 ZIP、TAR、JAR、WAR 等。它也可以将项目依赖打包到一个 JAR 文件中,但它的重点是创建复杂的分发包。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>org.example.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<!-- jar 携带依赖 -->
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<formats>
<format>jar</format>
<format>zip</format>
</formats>
<outputDirectory>${project.build.directory}</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
<appendAssemblyId>true</appendAssemblyId>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Apache Maven Dependency Plugin
使用 maven-dependency-plugin 插件,可以将项目中的依赖的 jar 包和 source 源码保存到指定的目录。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/dependency-lib</outputDirectory>
</configuration>
</execution>
<execution>
<id>src-dependencies</id>
<phase>package</phase>
<goals>
<!-- use copy-dependencies instead if you don't want to explode the sources -->
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<classifier>sources</classifier>
<outputDirectory>${project.build.directory}/dependency-source</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Apache Maven JAR Plugin
使用 maven-jar-plugin 插件,配置 jar 包中 MANIFEST.MF 内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<!-- 配置生成的 jar 包中,是否包含 pom.xml 和 pom.properties 这两个文件 -->
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<!-- 是否要把第三方 jar 文件名,放到 MANIFEST.MF 的 Class-Path 属性中 -->
<addClasspath>true</addClasspath>
<!-- 为 Class-Path 属性值添加一个前缀,依赖 jar 包放置到该目录即可 -->
<classpathPrefix>lib/</classpathPrefix>
<!-- 指定 MANIFEST.MF 中 Main-Class 属性值-->
<mainClass>org.example.Main</mainClass>
</manifest>
<!-- 手动添加 MANIFEST.MF 配置中的属性值 -->
<manifestEntries>
<Custom>value</Custom>
</manifestEntries>
</archive>
</configuration>
</plugin>
Apache Maven Resources Plugin
默认情况 maven 只打包 src/main/resource 下的资源文件,使用 maven-resources-plugin 插件可以将其它位置的资源文件也打包进 jar 包中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- 把源代码中的 xml 文件,打包到相应位置 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>copy-xmls</id>
<phase>process-sources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
多模块项目配置
项目结构:
1
2
3
4
5
6
7
8
9
10
11
12
parent-project
│ pom.xml # 父 POM 文件
│
├───module-a
│ pom.xml
│ src
│ ...
│
├───module-b
pom.xml
src
...
使用 ${revision}
管理多模块版本。
父项目 pom.xml 配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<?xml version="1.0" encoding="UTF-8"?>
<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.github.h0ny</groupId>
<artifactId>payload-generator-parent</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
<name>JPG - java payload generator</name>
<description>暂无描述</description>
<url>https://github.com/h0ny/payload-generator/</url>
<modules>
<module>payload-generator-core</module>
<module>payload-generator-memshell</module>
<module>payload-generator-ysoserial</module>
</modules>
<properties>
<revision>1.0.0</revision>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<hutool.version>5.8.32</hutool.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>${hutool.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<!-- Create sources.jar -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>3.0.0-M1</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
</configuration>
</plugin>
</plugins>
</build>
</project>
子项目 pom.xml 配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>com.github.h0ny</groupId>
<artifactId>payload-generator-parent</artifactId>
<version>${revision}</version>
</parent>
<dependencies>
<dependency>
<groupId>com.github.h0ny</groupId>
<artifactId>payload-generator-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
</dependencies>
<artifactId>payload-generator-memshell</artifactId>
<packaging>jar</packaging>
</project>
父模块中的 <dependencyManagement></dependencyManagement>
是为了方便管理子模块中的依赖版本,在父模块中定义后并不会自动在子模块中导入该模块,子模块中任然需要手动 dependencies 导入,只是不需要指定版本了。
而如果在父亲模块中使用 <dependencies></dependencies>
直接导入依赖,则所有子模块会自动导入该依赖。