Maven
Maven is a project management tool that is based on POM (project object model). It is used for projects build, dependency and documentation.
This blog is built on Windows 10 (x64-based):
- Maven: 3.8.7
- JDK 1.8
CONFIGURATION
settings.xml
In C:\Program Files\Java\apache-maven-3.8.7\conf\settings.xml
:
- to make
C:\maven-repo
a local Maven Repository, add the following toC:\Program Files\Java\apache-maven-3.8.7\conf\settings.xml
:
1<localRepository>C:\maven-repo</localRepository>
- JDK Version
C:\Program Files\Java\apache-maven-3.8.7\conf\settings.xml
:
1<profile>
2 <id>jdk-1.8</id>
3 <activation>
4 <activeByDefault>true</activeByDefault>
5 <jdk>1.8</jdk>
6 </activation>
7 <properties>
8 <maven.compiler.source>1.8</maven.compiler.source>
9 <maven.compiler.target>1.8</maven.compiler.target>
10 <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
11 </properties>
12</profile>
Environment Variables
First, check the version of current Java compiler by:
1$ java -version
Second, add JDK-related environment variables:
- set/new
JAVA_HOME
toC:\Program Files\Java\jdk1.8.0_231
- append
%JAVA_HONE%\bin
to%PATH%
- set/new
JAVA_TOOL_OPTIONS
to-Dfile.encoding=UTF-8
Third, add Maven-related environment variables:
- set/new
MAVEN_HOME
toC:\Program Files\Java\apache-maven-3.8.7
- set/new
M2_HOME
to%MAVEN_HOME%
- append
%MAVEN_HOME%\bin
to%PATH%
- set/new
MAVEN_OPTS
to-Xms256m -Xmx512m -Dfile.encoding=UTF-8
Fourth, open a new termianal and test Maven with command:
1$ mvn --version
BEGINNER PRACTICE
Maven uses 3 vectors to locate a *.jar
package:
groupId
: company/organization domain name in reverse orderartifactId
: project name, or module name in a projectversion
:SNAPSHOT
orRELEASE
Quick and Simple
In this section, I will create a quick and simple Maven Java project, which will serve as a template in the late project.
Considering my Blog address is https://mighten.github.io
, and this is a learning practice for Maven, so my group id will be io.github.mighten.learn-maven
, and artifact id will be maven-java
.
1$ mkdir C:\maven-workspace\learn-maven
2$ cd C:\maven-workspace\learn-maven
3
4$ mvn archetype:generate
Note:
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 7:
(Press Enter to confirm default value)Define value for property 'groupId':
io.github.mighten.learn-mavenDefine value for property 'artifactId':
maven-javaDefine value for property 'version' 1.0-SNAPSHOT: :
(Press Enter to confirm default value)Define value for property 'package' io.github.mighten.learn-maven: :
(Press Enter to confirm default value)Y: :
(Press Enter to confirm default value)
And the BUILD SUCCESS
is shown.
Change Dependencies
First, in path learn-maven/maven-jave/src
, delete the default Java files:
src/main/java/io/github/mighten/learn-maven/App.java
src/test/java/io/github/mighten/learn-maven/AppTest.java
Second, modify the version of JUnit
(in learn-maven/maven-jave/pom.xml
) from 3.8.1
to 4.12
MAVEN COMMANDS
change working directory to the directory of the current pom.xml
.
- clean
1$ mvn clean
delete the target
folder
- compile the
main
1$ mvn compile
target file in target/classes
- test
1$ mvn test-compile
2$ mvn test
target file in target/test-classes
- pack to
*.jar
1$ mvn package
- install into local Maven Repository
1$ mvn install
Trick:
1$ mvn clean install
DEPENDENCY MANAGEMENT
Dependency management is a core feature of Maven.
Scope
Scope is used to define the dependencies of a project, e.g., JUnit in pom.xml
has <scope>test</scope>
:
1<dependency>
2 <groupId>junit</groupId>
3 <artifactId>junit</artifactId>
4 <version>4.12</version>
5 <scope>test</scope>
6</dependency>
And we should notice:
- compile (default scope): used for both the compilation and the runtime of the project. But the Compile Scope does not use the classes in Test Scope
- test: used for testing, but not required for the runtime
- provided: used for dependencies that are part of the Java EE or other container environments. But the Provided Scope will not be packed into
*.jar
.
Scope Name | /main |
/test |
Develop | Deploy |
---|---|---|---|---|
compile | valid | valid | valid | valid |
test | N/A | valid | valid | N/A |
provided | valid | valid | valid | N/A |
These scopes help manage the classpath and control which dependencies are included at different stages of the build process.
Propagation
In the Maven tree, if the dependency of a child is compile-scope, then it can propagate to the parent; otherwise, if dependency of a child is test-scope or provided-scope, then it can not propagate to the parent.
For example, if I write a project_1.jar
, which adds a dependency to JUnit
with test scope. Then I create project_2
which uses a dependency to project_1.jar
. The JUnit
dependency will not be available for project_2
because JUnit
is in test scope; if I want to use JUnit
in project_2
, I have to explicitly declare JUnit
in pom.xml
of project_2
.
In addition, Maven can create an ASCII-styled dependency-tree graph, with the following command:
1$ mvn dependency:tree
Exclusion
Dependency Exclusions are used to fix *.jar
confrontations.
For example, if I create a project_3
will add dependencies on project_1.jar
(uses package A
version 1.1) and project_2.jar
(uses package A
version 1.6), then certainly the package A
will have confrontation with two version. To fix this issue, we usually choose the higher version (1.6) and exclude the lower version 1.1. So I will exclude package A
in dependency of project_1.jar
(in pom.xml
of project_3
):
1<dependency>
2 <groupId>io.github.mighten.learn_maven</groupId>
3 <artifactId>project_1</artifactId>
4 <version>1.0-SNAPSHOT</version>
5 <scope>compile</scope>
6
7 <exclusions>
8 <!--
9 to exclude package `A`,
10 (no need to specify version)
11 -->
12 <exclusion>
13 <groupId>A</groupId>
14 <artifactId>A</artifactId>
15 </exclusion>
16
17 <!--
18 to exclude other packages
19 <exclusion>
20 <groupId></groupId>
21 <artifactId></artifactId>
22 </exclusion>
23 -->
24 </exclusions>
25</dependency>
Inheritance
Dependency Inheritance allows child POM to inherit dependency from a parent POM. It is typically used to prevent version confrontations. In pom.xml
of parent
project:
-
set parent project
parent
to pack into POM file<packaging>pom</packaging>
, which will allow the parent to manage all the child projects. -
add tag
<dependencyManagement>
inpom.xml
ofparent
, to manage all the dependencies:
1<dependencyManagement>
2 <dependencies>
3 <dependency>
4 <groupId>org.springframework</groupId>
5 <artifactId>spring-core</artifactId>
6 <version>4.0.0.RELEASE</version>
7 </dependency>
8 <!-- other dependencies -->
9 </dependencies>
10</dependencyManagement>
Note: the packages are not really import into the parent
project
- add tag
<parent>
topom.xml
of every children:
1<parent>
2 <groupId>com.atguigu.maven</groupId>
3 <artifactId>pro03-maven-parent</artifactId>
4 <version>1.0-SNAPSHOT</version>
5</parent>
- add dependencies into children
pom.xml
, and since the version is declared in parentalpom.xml
, the version in the childrenpom.xml
can be omitted.
Aggregation
If we want to aggregate all of the children projects into one, we can config in parent.xml
(similar to inheritance):
1<modules>
2 <module>child_1</module>
3 <module>child_2</module>
4 <module>child_3</module>
5</modules>
Note: DO NOT use cyclic reference.