Maven
**Maven** is a *project management tool* that is based on *POM* (*project object model*). It is used for **projects build**, **dependency** and **documentation**.
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
In C:\Program Files\Java\apache-maven-3.8.7\conf\settings.xml:
- to make
C:\maven-repoa local Maven Repository, add the following toC:\Program Files\Java\apache-maven-3.8.7\conf\settings.xml:
<localRepository>C:\maven-repo</localRepository>- JDK Version
C:\Program Files\Java\apache-maven-3.8.7\conf\settings.xml:
<profile> <id>jdk-1.8</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.8</jdk> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> </properties></profile>First, check the version of current Java compiler by:
$ java -versionSecond, add JDK-related environment variables:
- set/new
JAVA_HOMEtoC:\Program Files\Java\jdk1.8.0_231 - append
%JAVA_HONE%\binto%PATH% - set/new
JAVA_TOOL_OPTIONSto-Dfile.encoding=UTF-8
Third, add Maven-related environment variables:
- set/new
MAVEN_HOMEtoC:\Program Files\Java\apache-maven-3.8.7 - set/new
M2_HOMEto%MAVEN_HOME% - append
%MAVEN_HOME%\binto%PATH% - set/new
MAVEN_OPTSto-Xms256m -Xmx512m -Dfile.encoding=UTF-8
Fourth, open a new termianal and test Maven with command:
$ mvn --versionMaven uses 3 vectors to locate a *.jar package:
groupId: company/organization domain name in reverse orderartifactId: project name, or module name in a projectversion:SNAPSHOTorRELEASE
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.
$ mkdir C:\maven-workspace\learn-maven$ cd C:\maven-workspace\learn-maven
$ mvn archetype:generateNote:
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.
First, in path learn-maven/maven-jave/src, delete the default Java files:
src/main/java/io/github/mighten/learn-maven/App.javasrc/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
change working directory to the directory of the current pom.xml.
- clean
$ mvn cleandelete the target folder
- compile the
main
$ mvn compiletarget file in target/classes
- test
$ mvn test-compile$ mvn testtarget file in target/test-classes
- pack to
*.jar
$ mvn package- install into local Maven Repository
$ mvn installTrick:
$ mvn clean installDependency management is a core feature of Maven.
Scope is used to define the dependencies of a project, e.g., JUnit in pom.xml has <scope>test</scope>:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope></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.
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:
$ mvn dependency:treeDependency 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):
<dependency> <groupId>io.github.mighten.learn_maven</groupId> <artifactId>project_1</artifactId> <version>1.0-SNAPSHOT</version> <scope>compile</scope>
<exclusions> <!-- to exclude package `A`, (no need to specify version) --> <exclusion> <groupId>A</groupId> <artifactId>A</artifactId> </exclusion>
<!-- to exclude other packages <exclusion> <groupId></groupId> <artifactId></artifactId> </exclusion> --> </exclusions></dependency>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
parentto pack into POM file<packaging>pom</packaging>, which will allow the parent to manage all the child projects. -
add tag
<dependencyManagement>inpom.xmlofparent, to manage all the dependencies:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.0.0.RELEASE</version> </dependency> <!-- other dependencies --> </dependencies></dependencyManagement>Note: the packages are not really import into the parent project
- add tag
<parent>topom.xmlof every children:
<parent> <groupId>com.atguigu.maven</groupId> <artifactId>pro03-maven-parent</artifactId> <version>1.0-SNAPSHOT</version></parent>- add dependencies into children
pom.xml, and since the version is declared in parentalpom.xml, the version in the childrenpom.xmlcan be omitted.
If we want to aggregate all of the children projects into one, we can config in parent.xml (similar to inheritance):
<modules> <module>child_1</module> <module>child_2</module> <module>child_3</module></modules>Note: DO NOT use cyclic reference.