maven actual combat summary, common operations in work

Mind map

Maven and construction

What is Maven

Accumulation of knowledge, experts and experts. Cross platform project management tools. Open source project organized by Apache. It mainly serves project construction, dependency management and project information management based on Java platform.

Similar to yum and apt on linux platform, npm in front-end field. Maven was formerly Ant. At present, the source code of tomcat is built and managed with Ant. More advanced tools include Gradle and Spring project.

What is build

What is build: the process of compiling, running unit tests, generating documents, packaging and deploying is build.

Steps to build:

  • clean up: delete the old class bytecode file compiled previously.

  • Compile: compile the java source program into a class bytecode file.

  • Test: automatic test, automatically call junit program.

  • report: the results of the test program execution.

  • Package: War package for dynamic Web project and jar package for java project.

  • install: copy the packaged files to the specified location in the "warehouse" (Maven specific concept).

  • deploy: copy the war package generated by the dynamic Web project to the Servlet container so that it can run.

Project skeleton

pom: Project Object Model

Root directory: project name
|---src: Source code
|---|---main:main program
|---|---|---java: Main program code path
|---|---|---resource: Main program configuration file path
|---|---test: test
|---|---|---java: Test code path
|---|---|---resource: Test profile path
|---pom.xml: maven configuration file

Simple demonstration

##  one   use   archetype   Command generation   maven   Simple skeleton
mvn archetype:generate -DarchetypeCatalog=internal

##  two   Compile the currently generated project
mvn compile

##  three   Use other commands
mvn test-compile  
mvn package  
mvn clean 
mvn install
mvn depoly Not for the time being

Coordinates and dependencies

What are coordinates

In analogy to plane geometry in mathematics, any coordinate (x, y) can uniquely identify a point in the plane.

This point corresponds to maven, which is the file of. jar,. war and other files.

Maven use   groupId,artifactId,version,packaging,classifier   And other elements to form their own coordinates, and define a set of such rules. As long as the correct coordinate element can be provided, Maven can find the corresponding component.

Coordinate element

  • groupId: defines the actual project to which the current Maven project belongs.

  • artifactId: defines a Maven project (module) in the actual project.

  • packaging: defines how Maven projects are packaged. jar,war,pom. The default is jar.

  • Version: defines the current version of the Maven project.

  • classifier: distinguish components with different contents built from the same artifact.

classifier usage scenario

Distinguish packages based on different JDK versions

<dependency>  
    <groupId>net.sf.json-lib</groupId>   
    <artifactId>json-lib</artifactId>   
    <version>2.2.2</version>  
    <classifier>jdk13</classifier>    
    <!--<classifier>jdk15</classifier>-->
</dependency> 

Distinguish between different components of the project

<dependency>  
    <groupId>net.sf.json-lib</groupId>   
    <artifactId>json-lib</artifactId>   
    <version>2.2.2</version>  
    <classifier>jdk15-javadoc</classifier>    
    <!--<classifier>jdk15-sources</classifier>  -->
</dependency>

The component name corresponds to the coordinate. The general rule is: artifactid version [- classifier]. Packaging.

Dependency declaration

<dependencies>
  <dependency>
    <groupId></groupId>
    <artifactId></artifactId>
    <version></version>
    <type></type>
    <optional></optional>
    <exclusions>
      <exclusion>
        <artifactId></artifactId>
        <groupId></groupId>
      </exclusion>
      ...
    </exclusions>
  </dependency>
  ...
</dependencies>
  • groupId, artifactId, version: the dependent basic coordinates.

  • Type: the type of dependency. It corresponds to the packaging corresponding to the project. Generally, it does not need to be declared.

  • Scope: the dependent scope, which will be explained later.

  • Optional: mark whether the dependency is optional.

  • exclusions: used to exclude transitive dependencies.

Dependency range

  • Compile: compile dependency range

    If not specified, the dependency range is used by default. The three Classpaths are valid for compiling, testing and running. For example, spring core.

  • test: test dependency range

    It is only valid for testing classpath. It is only required when compiling and running tests. It will not be typed in when packaging. Such as JUnit.

  • Provided: dependency range provided

    classpath is valid for compilation and testing, but not for runtime. For example, servlet API is required when compiling and testing projects, but in actual operation, the container has been provided, and there is no need for repeated maven references.

  • Runtime: runtime dependency range

    The classpath is valid for testing and running, but not when compiling the main code. For example, the implementation package of jdbc driver. Specific JDBC drivers are required only when executing tests or running projects.

  • System: system dependency range

    It is exactly the same as the provided dependency range, but when using this range, the path of the dependent file must be explicitly specified through the systemPath element. Since such dependencies are not resolved through the maven repository and are often bound to the native system, the build may not be portable, so they should be used with caution. The systemPath element can reference environment variables, such as:

    <dependencies>
      <dependency>
        <groupId>javax.sql</groupId>
        <artifactId>jdbc-stdxt</artifactId>
        <version>2.0</version>
        <scope>system</scope>
        <systemPath>${java.home}/lib/rt.jar</systemPath>
      </dependency>
    </dependencies>
    
  • Import: import dependency range

    It only takes effect in the dependency management tab and imports the content of the dependency management node in the defined pom file

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-framework-bom</artifactId>
          <version>4.3.16.RELEASE</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>
    

Dependency mechanism and characteristics

Dependency delivery

  • A - > b (compile): the first direct dependency

  • B - > C (compile): the second direct dependency

  • A - > C (compile): transitive dependency

When configured in A

<dependency>  
    <groupId>com.B</groupId>  
    <artifactId>B</artifactId>  
    <version>1.0</version>  
</dependency>

The C package is automatically imported.

The scope of transitivity dependency is shown in the following figure:

Dependent mediation

When there is a problem with transitive dependency, you can clearly know which dependency path the transitive dependency is introduced from.

1, Principle of the shortest path first

  • A->B->C->X(1.0)

  • A->D->X(2.0)

Since only one version of package can be imported, import X(2.0) according to the shortest path

2, Principle of first declaration priority

  • A->B->Y(1.0)

  • A->C->Y(2.0)

At this time, since the length of dependent paths is consistent, the first declaration takes precedence. On the premise of consistent path length, if the declaration order of B dependency in POM file is before that of C dependency, Y(1.0) will be introduced. The following dependencies can be used for testing:

<dependencies>
  <dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.4.1</version>
    <exclusions>
      <exclusion>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
      </exclusion>
    </exclusions>
  </dependency>

  <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.9</version>
    <exclusions>
      <exclusion>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
      </exclusion>
    </exclusions>
  </dependency>

  <dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
  </dependency>

</dependencies>

Here is a point that needs special attention. See the following dependencies:

<dependencies>
  <dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.11</version>
  </dependency>

  <dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
  </dependency>
</dependencies>

According to two principles, the expected result should be that the build of version 1.11 will be relied on. But the actual results rely on version 1.10. what! Isn't this a violation of maven's first definition principle of relying on mediation?

In fact, this is the function of the dependency plug-in. By default, the replication strategy is adopted. When the build declaration is in the same pom and the groupid is consistent with the artifact ID, the latest declaration shall prevail, and the later ones overwrite the previous ones.

Note that the function of relying on mediation is not involved here. My understanding is that dependency mediation only occurs when building from different POMs. At this time, the build declaration is in the same pom, so dependency mediation will not be triggered.

Optional dependency

A - > b, B - > x (optional), B - > y (optional).

Project A depends on project B, and project B depends on projects X and Y.

In theory, project A will rely on projects B, X and Y.

However, X and Y dependencies may be mutually exclusive to B. for example, B is a database isolation package that supports multiple databases MySQL and Oracle. These two databases need to be supported when building B project, but only one database will be relied on when using this toolkit.

At this time, you need to declare X and Y as optional dependencies in the B project pom file, as follows:

<dependency>  
    <groupId>com.X</groupId>  
    <artifactId>X</artifactId>  
    <version>1.0</version>  
    <optionnal>true</optionnal>
</dependency>

<dependency>  
    <groupId>com.Y</groupId>  
    <artifactId>Y</artifactId>  
    <version>1.0</version>  
    <optionnal>true</optionnal>
</dependency>

After being identified with the optionnal element, it will only affect the current project B. when other projects depend on project B, these two dependencies will not be passed.

Project A depends on project B. if the actual application database is x, the X dependency needs to be explicitly stated in A's pom.

Warehouse

Warehouse classification: including local warehouse and remote warehouse. The remote warehouse includes private server and central warehouse. Search build order:

  • Local warehouse

  • repository in maven settings profile;

  • The repository defined in the profile in pom.xml;

  • Repositories in pom.xml (found in the order of definition);

  • maven settings mirror;

  • Central central warehouse;

life cycle

Maven's life cycle is to abstract and unify all construction processes, including almost all construction steps such as project cleaning, initialization, compilation, testing, packaging, integration testing, verification, deployment and site generation.

Maven's life cycle is abstract and does not do any practical work. The actual tasks are left to the plug-in.

This means that Maven only defines the overall structure of the algorithm in the parent class, and the child class controls the actual behavior by overriding the method of the parent class (Template Method in design pattern). The pseudo code is as follows:

public abstract class AbstractBuilder {
    public void build() {
        init();
        compile();
        test();
        package();
        integrationTest();
        deploy();
    }
    
    protected abstract void init();
    protected abstract void compile();
    protected abstract void test();
    protected abstract void package();
    protected abstract void integrationTest();
    protected abstract void deploy();
}

Three life cycles

Maven's life cycle is not a whole. Maven has three sets of independent life cycles: clean, default and site.

  • clean   The purpose of the life cycle is to clean up the project;

  • default   The purpose of the life cycle is to build the project;

  • site   The purpose of the life cycle is to establish the project site;

Single life cycle execution sequence

Each life cycle contains some phases, which are sequential, and the subsequent phases depend on the previous phases.

Take the clean life cycle as an example. It includes pre clean, clean and post clean phases. When pre clean is called, only the pre clean phase can be executed;

When clean is called, the pre clean and clean phases are executed sequentially, and so on.

Relationship between life cycles

The three sets of life cycles are independent of each other. Users can call only a certain stage of the clean life cycle or only a certain stage of the default life cycle without any impact on other life cycles.

For example, when a user invokes the clean phase of the clean lifecycle, no phase of the default lifecycle is triggered, and vice versa.

Detailed explanation of each stage of the life cycle

clean

Life cycle phasedescribe
pre-cleanPerform some work that needs to be done before cleaning.
cleanClean up the files generated by the last build.
post-cleanPerform some work that needs to be done after cleaning.

default

There are 23 stages, and only the key steps are introduced here, as shown in the table below:

Life cycle phasedescribe
validateCheck whether the project configuration is correct and whether all necessary information for completing the construction process can be obtained.
initializeInitializes the build state, such as setting properties.
generate-sources
process-sourcesProcess the project resource file and the project master resource file. Generally speaking, the contents of src/main/resources directory are copied to the main classpath directory of the project output after variable replacement.
generate-resources
process-resources
compileCompile the main source code of the project. Generally speaking, compile the java files in src/main/java directory to the main classpath directory of the project output.
process-classesHandle compiled files, such as Java Class bytecode enhancement and optimization.
generate-test-sources
process-test-sourcesProcess project test resource files. Generally speaking, the contents of src/test/resources directory are copied to the test classpath directory output by the project after variable replacement.
test-compileCompile the test code for the project. Generally speaking, compile the java files in src/test/java directory to the test classpath directory of the project output.
process-test-classes
testRun tests using an appropriate unit test framework, such as JUnit.
prepare-packageBefore the actual packaging, do whatever is necessary to prepare the packaging.
packageGet the compiled code and package it in a publishable format, such as JAR, WAR or EAR files.
pre-integration-testPerform the required actions before the integration test is executed. For example, set the required environment variables.
integration-testProcess and deploy the necessary engineering packages into the environment where the integration test can run.
post-integration-testPerform the necessary operations after the integration test is executed. For example, clean up the environment.
verifyRun inspection operations to verify that the work package is effective and meets quality requirements.
installInstall the project package into the local warehouse, which can be used as a dependency of other local projects.
deployCopy the final project package to the remote warehouse for sharing with other developers and projects.

site

Life cycle phasedescribe
pre-sitePerform some work that needs to be done before building the project site.
siteGenerate project site documents.
post-sitePerform some work that needs to be done after building the project site.
site-deployPublish the generated project site to the server.

plug-in unit

Maven's three sets of life cycle definitions do not do any actual work in each stage. The actual work is completed by the plug-in, and each life cycle stage is completed by the goal of the plug-in. Declare the following in the pom file (package the source file plug-in):

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-source-plugin</artifactId>
      <version>2.1.1</version>
      <executions>
        <execution>
          <id>attach-sources</id>
          <phase>verify</phase>
          <goals>
              <goal>jar-no-fork</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Plug in target

A plug-in may have multiple functions, and each function is a target. For example, Maven dependency plugin has more than ten goals, and each goal corresponds to a function.

The targets of the plug-in are dependency:analyze, dependency:tree, and dependency:list.

General writing method: the prefix of the plug-in is before the colon, and the target of the plug-in is after the colon. For example, compiler:compile.

Plug in binding

Built in binding

For fast build, Maven has a set of built-in plug-in bindings. The three sets of life cycle plug-in bindings are as follows (in fact, they are the binding between each life cycle stage and the goal of the plug-in).

The construction method of default life cycle is related to its packaging type, which is specified in POM packaging. There are generally two types: jar and war. The following is the relationship between the default binding plug-in and the life cycle:

Custom binding

Custom binding allows us to control the combination of plug-in objectives and life cycle. Take the source jar that generates the main code of the project as an example.

The plug-in used and its target are Maven source plugin: jar no fork. Bind it to the default life cycle stage verify (any stage of three sets of life cycles can be specified arbitrarily).

<build>
  <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <version>2.1.1</version>
        <executions>
          <execution>
            <id>attach-sources</id> 
            <!-- Specifies which phase of the lifecycle the action is in -->
            <phase>verify</phase> 
            <goals>
               <!-- Specify which targets to execute the binding plug-in -->
                <goal>jar-no-fork</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
  </plugins>
</build>

Plug in configuration

  • Use command line configuration

    Add the - D parameter to the maven command with a parameter key = parameter value to configure the plug-in target parameters.

    For example, the Maven surefire plugin provides a maven.test.skip parameter. When the value is true, the test execution will be skipped:

     -- contrast mvn install
    mvn install –Dmaven.test.skip=true
    
  • Use pom global configuration

    When declaring a plug-in, make a global configuration for the plug-in, and all subsequent users of the plug-in should follow this configuration. For example, specify Maven compile plugin to compile the source file of version 1.7:

    <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-compiler-plugin</artifactId>
       <configuration>
           <fork>true</fork>
           <source>1.7</source>
           <target>1.7</target>
       </configuration>
    </plugin>
    

Aggregation and inheritance

Aggregation: in order to build multiple project modules at one time, you need to aggregate multiple project modules

<modules>
    <module>Module I</module>
    <module>Module II</module>
    <module>Module III</module>
</modules>

Inheritance: in order to eliminate duplication, many of the same configurations are extracted, such as dependency, grouptId, version, etc

<parent>  
    <groupId>com.xxxx.maven</groupId>
    <artifactId>parent-project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../ParentProject/pom.xml</relativePath>  
</parent>

The following elements can be inherited:

  • groupId, project group ID;

  • Version, project version;

  • Description, item description information;

  • Organization, organization information of the project;

  • Inception year, the year when the project was founded;

  • developers, project developer information;

  • contributors, the contributor information of the project;

  • Distribution management, project deployment information;

  • Issue management, defect tracking system information of the project;

  • ciManagement, continuous integration system information of the project;

  • scm, version control system information of the project;

  • mailingLists, mailing list information of the project;

  • Properties, custom Maven properties;

  • dependencies, the dependency configuration of the project;

  • Dependency management, the dependency management configuration of the project;

  • repositories, warehouse configuration of the project;

  • build, including source directory configuration, output directory configuration, plug-in configuration, plug-in management configuration, etc;

  • reporting, including report output directory configuration and report plug-in configuration of the project.

Note that the following elements cannot be inherited:

  • artifactId

  • name

  • prerequisites

Relationship between aggregation and inheritance

  • The common point between the two is that the playing method must be pom

  • In a real project, a pom is both an aggregate pom and a parent pom

Note: the dependencies introduced by using dependencies in the parent pom will also be inherited by the child pom, so do not put too many actual dependencies on the parent pom. The parent pom is only used for management and uses the dependency management tag.

Flexible construction

Use properties, resources plug-in resource filter function and Maven's profile function to realize flexible environment switching

attribute

Through the properties element, users can customize one or more Maven attributes, and then use ${attribute name} to reference the attribute elsewhere in pom. The greatest significance of this method is to eliminate duplication.

1, Built in properties

  • ${basedir}   Represents the root directory of the project, that is, the directory containing the pom.xml file

  • ${version}   Equivalent to   Or {pom.version} indicates the project version

2, POM properties

All elements in POM can use project. For example, ${project.artifactId} corresponds to the value of < project > element. Common POM attributes include:

  • ${project.build.sourceDirectory}  : The main source directory of the project. The default is src/main/java /

  • ${project.build.testSourceDirectory}  : The test source directory of the project. The default is / src/test/java /

  • ${project.build.directory}  : Project build output directory, default to target /

  • ${project.build.outputDirectory}  : The project main code compilation output directory is target/classes /

  • ${project.build.testOutputDirectory}  : The project test code compilation output directory is target/testclasses /

  • ${project.groupId}: groupId of the project

  • ${project.artifactId}  : Artifactid of the item

  • ${project.version}  : Version of the project, equivalent to ${version}

  • ${project.build.finalName}  : The name of the project packaging output file. The default is  $ {project.artifactId}${project.version}

3, Custom properties

Custom Maven attribute under element in pom

<properties>
    <swagger.version>2.2.2</swagger.version>
</properties>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>${swagger.version}</version>
</dependency>

4, Settings properties

All settings in settings.xml can be set through settings. Prefix reference is the same as POM attribute.

For example, ${settings.localRepository} points to the address of the user's local warehouse

5, Java system properties

All Java system properties can be referenced using Maven properties. For example, ${user.home} points to the user directory.

You can view all Java system properties from the command line mvn help:system

6, Environment variable properties

All environment variables can be referenced using the Maven attribute starting with env. For example, ${env.JAVA_HOME} refers to Java_ The value of the home environment variable.

You can also view all environment variables from the command line mvn help:system.

7, Parent project properties

The variables in the pom of the parent project are prefixed   quote. The version of the parent project can also refer to {parent.version}

Profile

The profile feature allows us to define multiple profiles, and then each profile corresponds to different activation conditions and configuration information, so as to achieve the effect of using different configuration information in different environments.

A profile can be declared in the following places:

  • m.xml: the profile declared here is only valid for the current project

  • User settings.xml: the profile in. m2/settings.xml is valid for the Maven project of the user

  • Global settings.xml: conf/settings.xml, which is valid for all Maven items on the machine

Example:

<project>
  ...
  <profiles>
    <profile>
      <id>dev</id>
      <properties>
        <active.profile>dev</active.profile>
        <key1>value1</key1>
        <key2>value2</key2>
      </properties>

      <!-- Default activation configuration -->
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <!-- In this profile Dependency introduced under -->
      <dependencies>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>3.2.4.RELEASE</version>
        </dependency>
      <dependencies>
      <!-- In this profile Variable file to be loaded under -->
      <build>
        <filters>
          <filter>../profile/test-pre.properties</filter>
        </filters>
      </build>
    </profile>
  </profiles>
  ...
</project>

Keywords: Java Gradle Maven

Added by DefunctExodus on Mon, 08 Nov 2021 02:24:13 +0200