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:

  1. to make C:\maven-repo a local Maven Repository, add the following to C:\Program Files\Java\apache-maven-3.8.7\conf\settings.xml:
1<localRepository>C:\maven-repo</localRepository>
  1. 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 to C:\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 to C:\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 order
  • artifactId: project name, or module name in a project
  • version: SNAPSHOT or RELEASE

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-maven
  • Define value for property 'artifactId': maven-java
  • Define 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.

  1. clean
1$ mvn clean

delete the target folder

  1. compile the main
1$ mvn compile

target file in target/classes

  1. test
1$ mvn test-compile
2$ mvn test

target file in target/test-classes

  1. pack to *.jar
1$ mvn package
  1. 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:

  1. set parent project parent to pack into POM file <packaging>pom</packaging>, which will allow the parent to manage all the child projects.

  2. add tag <dependencyManagement> in pom.xml of parent, 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

  1. add tag <parent> to pom.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>
  1. add dependencies into children pom.xml, and since the version is declared in parental pom.xml, the version in the children pom.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.


* This blog was last updated on 2023-06-21 00:00