The original address: Introduction to Maven, read this enough

Blog: tengj.top/

preface

Maven is used in our daily development. On the first day of the New Year, I sorted out the basic concepts of Maven that I have seen, and used them as an introduction and reference.

The body of the

Maven concept

As a build tool, Maven not only helps us automate builds, but also abstracts the build process and provides the implementation of build tasks. The fact that it is cross-platform and provides a consistent interface to the outside world is enough to make it an excellent and popular build tool.

Maven is not only a build tool, but also a dependency management tool and project management tool, providing a central repository that helps me automatically download artifacts.

The installation of the maven

One: Because I am a Windows system, so here only describes how to install Windows, before installing Maven, first make sure you have installed JDK.

Two: Go onThe Maven websiteDownload interface Download the version you want and unzip it to the directory you want

Three: finally set the environment variables, to configure the Maven installation to the operating system environment, mainly configurationM2_HOME andPATHTwo items, as shown here

So when you’re done, verify that, open doc and say MVN -v how do you get the following information to say that the configuration is successful

Maven directory

  • Bin directory:

This directory contains the scripts that MVN runs to configure the Java commands, prepare the CLASspath and associated Java system properties, and then execute the Java commands.

  • The boot directory:

This directory contains only one file, plexus-classWorlds-2.5.2.jar. Plexus-classworlds is a classloader framework that provides richer syntax for configuration than the default Java classloader, and Maven uses it to load its own class libraries.

  • The conf directory:

This directory contains a very important file, settings.xml. By modifying this file directly, we can customize Maven’s behavior globally on the machine. In general, we prefer to copy the file to the ~/.m2/ directory (~ represents the user directory) and then modify the file to customize Maven’s behavior user-wide.

  • Lib directory:

This directory contains all the Java libraries required for the Maven runtime. Maven itself is developed in modules, so users can see files such as maven-core-3.0.jar, maven-model-3.0.jar, etc. There are also some third-party dependencies that Maven uses such as Commons-cli-1.2. jar, Commons-lang-2.6. jar, and so on.

Description of Maven common commands

  • MVN clean: To run a clean operation (by default, the data in the target folder will be cleaned).
  • MVN clean compile: Indicates that the code is compiled to the target folder after the clean up is run.
  • MVN Clean test: Runs a clean and test.
  • MVN Clean Package: Run clean and package.
  • MVN Clean Install: Runs clean and install, which installs the packaged package into a local repository so that other projects can call it.
  • MVN Clean deploy: Run clean deploy and publish (publish to a private server).

Most of the above commands are written in conjunction, but you can also execute them separately. This is live, depending on your preferences and requirements. Eclipse Run as provides common commands for Maven projects.

Setting the HTTP Proxy

Edit the seeting.xml file. Sometimes your company will require you to use a secure proxy to access the Internet for security reasons. In this case, you need to configure the HTTP proxy for Maven so that it can access the external repository properly to download the resources it needs. Make sure you don’t have direct access to the public Maven central repository. Run ping repo1.maven.org to check the network. If you really need a proxy, check that the proxy server is working first. For example, if we have a proxy service whose IP address is 218.14.227.197 and port is 3128, we can run Telnet 218.14.227.197 3128 to check whether the port is available at that address. If an error message is displayed, obtain the correct proxy service information first. If the Telnet connection is correct, press CTRL +], then q, and press Enter to exit.

After checking, edit the ~/.m2/settings. XML file (if it is not available, copy $M2_HOME/conf/settings. XML). Add agent configuration as follows:

<settings>.<proxies>  
    <proxy>  
      <id>my-proxy</id>  
      <active>true</active>  
      <protocol>http</protocol>  
      <host>218.14.227.197</host>  
      <port>3128</port>  
      <! -- <username>***</username> <password>***</password> <nonProxyHosts> repository.mycom.com|*.google.com </nonProxyHosts> -->  
    </proxy>  
  </proxies>.</settings> 
Copy the code

This is a simple configuration. Multiple proxy elements can be created by proxies. If multiple proxy elements are declared, the first active proxy will take effect by default. A proxy with id my-proxy is declared. Active is true to activate the proxy. Protocol is the proxy protocol used, in this case HTTP. Of course, the most important thing is to specify the correct hostname (host element) and port (port element). The XML configuration commented out in the username, password, nonProxyHosts several elements. When the proxy service requires authentication, you need to configure the username and password. NonProxyHost element is used to specify which hosts don’t need agent, you can use the symbol “|” to separate multiple host name. In addition, this configuration also supports wildcards. For example, *. Google.com indicates that all domain names ending with google.com are not accessed through the proxy.

Maven plug-in installed, based on IDEA

The blogger now uses IDEA for development, so here’s how to configure the IDEA to bring in the Maven we downloaded above

Maven use


      
<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.tengj</groupId>
    <artifactId>springBootDemo1</artifactId>
    <version>0.0.1 - the SNAPSHOT</version>
    <name>springBootDemo1</name>
</project>
Copy the code

The first line of the code is the XML header, which specifies the version and encoding of the XML document. Project is the root element of all POM.xml, and it also declares some POM-related namespaces and XSD elements. The first child of the root element, modelVersion, specifies the version of the current POM model. For Maven3, it can only be the 4.0.0 code that includes groupId,artifactId, and version. These three elements define the basic coordinates of a project, and in Maven’s world, any JAR, POM, or JAR is identified based on these basic coordinates.

GroupId defines which group the project belongs to, naming it arbitrarily, such as Google’s MyApp project, which is called com.google.myApp

ArtifactId defines the unique ID of the current Maven project in the group, such as hello-world.

Version specifies the current version of the project, 0.0.1-SNAPSHOT. SNAPSHOT means a SNAPSHOT, indicating that the project is under development and unstable.

The name element provides a more user-friendly project name, and while this is not required, it is recommended that you declare a name for each POM to facilitate information exchange

Configuration of dependencies

<project>.<dependencies>
    <dependency>
        <groupId>The actual project</groupId>
     <artifactId>The module</artifactId>
     <version>version</version>
     <type>Depend on the type</type>
     <scope>Depend on the range</scope>
     <optional>Whether dependencies are optional</optional><! -- Used primarily to exclude transitive dependencies --><exclusions>
         <exclusion>
           <groupId>...</groupId>
          <artifactId>...</artifactId>
       </exclusion>
     </exclusions>
  </dependency>
<dependencies>.</project>
Copy the code

Under the root project element, dependencies can contain one or more Dependency elements to declare one or more project dependencies. The elements that each dependency can contain are:

  • GrounpId, artifactId, and Version: The base coordinates of all dependencies. For any dependency, the base coordinates are the most important. Maven uses the coordinates to find the required dependencies.
  • Type: The type of dependency, packaging, defined for the project coordinates. In most cases, this element does not have to be declared; the default value is JAR
  • Scope: Scope of the dependency
  • Optional: Whether tag dependencies are optional
  • Exclusions: Exclusions are used to exclude transitive dependencies

Depend on the range

Dependency scopes are used to control the relationship between dependencies and the three classpath(compile classpath, test classpath, and run classpath). Maven has the following dependencies:

  • **compile:** compile dependent range. If not specified, the dependency range is used by default. Maven dependencies using this dependency scope are valid for compiling, testing, and running all three classpath types. The typical example is Spring-Code, which needs to be used at compile, test, and run time.
  • Test: Tests the dependency range. Maven dependencies that use the sub-dependency scope are only valid for testing the CLASspath, and are not available when compiling the main code or running project usage. A typical example is Jnuit, which is needed only when compiling test code and running tests.
  • Provided: Provided: Provided: Provided Maven dependencies that use this dependency scope are valid for compiling and testing the CLASSPath, but not at runtime. A typical example is servlet-API, which is required when compiling and testing a project, but when running a project, Maven does not need to introduce it repeatedly because of the containers and provisioning.
  • ** Runtime :** Runtime dependency range. Maven dependencies that use this dependency scope are valid for testing and running the CLASspath, but not when compiling the main code. A typical example is a JDBC driver implementation. The main code of a project requires only the JDBC interface provided by the JDK for compilation, and only the specific JDBC driver that implements the above interface is required when executing tests or running the project.
  • **system:** System dependency range. This dependency relates to the three CLASspath types and is exactly the same as the Provided dependency scope. However, when using system-scope dependencies, you must specify the path to the dependency file through the systemPath element. Because such dependencies are not resolved through Maven repositories and are often tied to native systems, they may constitute a non-portable build and should be used with caution. SystemPath elements can reference environment variables such as:
<dependency>
    <groupId>javax.sql</groupId>
    <artifactId>jdbc-stdext</artifactId>
    <Version>2.0</Version>
    <scope>system</scope>
    <systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
Copy the code
  • **import:** Import dependency range. This dependency scope has no real impact on the three classpath types.

The above dependencies, except import, relate to the three CLASspath as follows:

Transitive dependence

For example, for an account-email project, account-email has a spring-code dependency in the compile scope, and spring-code has a commons-logging dependency in the compile scope. Commons -logging is a range dependency of account-email’s compile, and Commons -logging is a transitivity dependency of account-email

With transitive dependencies, you don’t have to worry about what the Spring Framework depends on or introduce unnecessary dependencies when you use it. Maven resolves the POM of each direct dependency and introduces the necessary indirect dependencies into the current project in the form of transitional dependencies.

Depend on the range

Assuming that A depends on B and B depends on C, we say that A is the first direct dependence on B,B is the second direct dependence on C, and A is transitively dependent on C. The scope of the first direct dependency and the second direct dependency determine the scope of the transitive dependency. As shown in the figure below, the leftmost row represents the scope of the first direct dependency, the uppermost row represents the scope of the second direct dependency, and the intersecting cells in the middle represent the scope of the transitive dependency.

From the picture above, we can find such a rule:

  • When the scope of the second direct dependency is compile, the scope of the transitive dependency is the same as the scope of the first direct dependency.
  • When the scope of the second direct dependency is test, the dependency is not passed;
  • So if the scope of the second direct dependency is provided, you just pass in the first direct dependency, which is also the scope of provided;
  • When the scope of the second direct dependency is Runtime, the scope of the transitive dependency is the same as the scope of the first direct dependency, but outside the compile column, the scope of the transitive dependency is runtime.

Sometimes, when transitive dependencies are the problem, it is necessary to be clear which dependency path the transitive dependency is introduced from. This is the role of dependency mediation. There are two principles of dependency mediation: 1. The closest path is preferred. – A – > B > C – > X (1.0), A – > D – > X (2.0), X is A transitive dependencies, but there are two versions of the two dependent path X, so according to the first principle, A – > D – > X (2.0) path is short, so use 2 X (2.0) will be resolved. A->B->Y(1.0), A->C->Y(2.0),Y(1.0),Y(1.0),Y(2.0),Y(1.0),Y(2.0),Y(1.0) and Y(2.0) are the same.

## Optional dependencies

As shown in the figure, A depends on B, B depends on X and Y. If all three ranges are compile, then X and Y are transitive dependencies of A’s compile range, but if I want X and Y not to be transitive dependencies of A, I don’t give them to him. You need to configure the optional dependencies mentioned below.

<project>  
    <modelVersion>4.0.0</modelVersion>  
    <groupId>com.juvenxu.mvnbook</groupId>  
    <artifactId>project-b</artifactId>  
    <version>1.0.0</version>  
    <dependencies>  
        <dependency>  
            <groupId>mysql</groupId>  
            <artifactId>mysql-connector-java</artifactId>  
            <version>5.1.10</version>  
            <optional>true</optional>  
        </dependency>  
        <dependency>  
            <groupId>postgresql</groupId>  
            <artifactId>postgresql</groupId>  
            <version>8.4-701. Jdbc3</version>  
            <optional>true</optional>  
        </dependency>  
    </dependencies>  
</project>  
Copy the code

Configuration is also simple and added in dependencies

<optional>true</optional>
Copy the code

If A wants to use X,Y has to add the dependency directly.

Eliminate dependence on

Sometimes you introduce dependencies that you don’t want, and you want to introduce dependencies that you do want. For example, in the following image, spring-boot-starter- Web comes with logback. I want to introduce Log4j2, so I will exclude logback dependencies first. Just introduce the desired package

Exclude dependent code structures:

<exclusions>
    <exclusion>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-logging</artifactId>
    </exclusion>
</exclusions>
Copy the code

Note here that exclustion only requires groupId and artifactId, not version elements, because only groupId and artifactId are needed to uniquely locate a dependency in the dependency graph.

Classified depend on

Sometimes we introduce many dependency packages from different modules of the same project, so they all have the same version number. In this case, we can use properties to manage the version number uniformly

<project>  
    <modelVersion>4.0.0</modelVersion>  
    <groupId>com.juven.mvnbook.account</groupId>  
    <artifactId>accout-email</artifactId>  
    <version>1.0.0 - the SNAPSHOT</version>  
    <properties>  
        <springframework.version>1.5.6</springframework.version>  
    </properties>  
    <dependencies>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-core</artifactId>  
            <version>${springframework.version}</version>  
        </dependency>   
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-beans</artifactId>  
            <version>${springframework.version}</version>  
        </dependency>         
    </dependencies>  
</project>  
Copy the code

As shown in the figure, pass first

</properties>Here defines the version you want first</properties>
Copy the code

, and then rely on ${} to introduce your attributes below.

warehouse

This section describes the origin, layout, classification, configuration, internal working mechanism, mirroring, and other concepts of the warehouse

The Origin of warehouses

In Maven’s world, any dependency, plug-in, or the output of a project build is called an artifact. Thanks to the coordinate mechanism, any Maven project uses any of the artifacts in exactly the same way. Based on this, Maven can store the shared artifacts of all Maven projects in a unified location, called the repository.

Actual Maven projects will no longer store their dependency files individually; they will simply declare the coordinates of those dependencies, and when needed (for example, when the dependencies need to be added to the classpath to compile the project), Maven will automatically find the artifacts in the repository based on the coordinates and use them.

To achieve reuse, artifacts that can be generated after a project is built can also be installed or deployed to a repository for use by other projects.

Warehouse layout

Each component has a unique coordinate that defines its unique storage path in the repository. This is Maven’s repository layout. The path to the corresponding relationship between coordinates the groupId/artifactId/version/artifactId – version. Packaging. For example, let’s look at the following pagination plugin dependencies:

<dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper-spring-boot-starter</artifactId>
      <version>1.1.0</version>
</dependency>
Copy the code

Then his corresponding warehouse path is like this:

The Maven repository is based on a simple file system, and we understand how it is stored, so when we encounter some warehouse-related problems, we can easily find the relevant files and locate the problem.

Classification of warehouse

Local repository

In general, there are no directories in the Maven project directory, such as lib/, for storing dependent files. When Maven executes compilations or tests, if dependency files are needed, it always uses the local repository’s dependency files based on coordinates.

By default, both Windows and Linux users have a.m2/repository directory in their user directory. If you want to customize the local repository directory address. You can edit the file ~/.m2/settings. XML to set the localRepository element to the desired repository address, for example:

<settings>
<localRepository>D:\java\repository\</localRepository>
</settings>
Copy the code

Thus, the user’s local repository address is set to D:\ Java \repository\. Note that the ~/.m2/settings. XML file does not exist by default and users will need to copy the $M2_HOME/conf/settings. XML file from the Maven installation directory before editing it.

Remote warehouse – Central warehouse

Since the original local repository is empty, Maven must know that at least one remote repository is available in order to download the required artifacts when executing Maven commands. A central repository is the default remote repository, and the Maven installation file comes with a central repository configuration.

The central repository contains most of the most popular open source Java artifacts in the world, along with source code, author information, SCM, information, license information, and so on. It receives about 100 million visits from Java programmers around the world every month, which shows its contribution to the world’s Java developers.

Remote warehouse – private server

Private server is a special kind of remote warehouse, it is set up in the local area network warehouse service, private server proxy wan remote warehouse, for the local area network Maven users use. When Maven needs to download a component, it requests it from the private server. If the component does not exist on the private server, it downloads it from an external remote repository, buffers it on the private server, and then serves Maven’s download request. As a result, some components that cannot be downloaded from external repositories can be uploaded locally to private servers for everyone to use. Benefits of private server:

  • Save your extranet speed
  • Speed up Maven builds
  • Deploying third-party builds
  • Improve stability and control
  • Reduce the load of central warehouse

Configuration of the remote repository

In the usual development, we often don’t use the default central warehouse, warehouse in the middle of the default access speed is slow, perhaps many people visit, sometimes can’t satisfy the demand of our project, may need to some of the components of the project is not in the warehouse, and in other remote warehouse, such as JBoss Maven repository. In this case, you can configure the repository in pom.xml as follows:

<! -- Configure the remote repository -->
    <repositories>
        <repository>
            <id>jboss</id>
            <name>JBoss Repository</name>
            <url>http://repository.jboss.com/maven2/</url>
            <releases>
                <enabled>true</enabled>
                <updatePolicy>daily</updatePolicy>
            </releases>
            <snapshots>
                <enabled>false</enabled>
                <checksumPolicy>warn</checksumPolicy>
            </snapshots>
            <layout>default</layout>
        </repository>
    </repositories>
Copy the code
  • **repository:** Under repositories, you can use the repository child element to declare one or more remote repositories.
  • **id: specifies the unique ID of the repository declaration. It is important to note that Maven’s own central repository uses the ID central. If other repository declarations use this id, the configuration of the central repository will be overwritten.
  • **name: the name of ** warehouse, let us intuitively and conveniently know which warehouse is, temporarily did not find other too big meaning.
  • **url: ** points to the repository address. In general, this address is based on the HTTP protocol, and Maven users can open the repository address to browse artifacts in a browser.
  • Releases and snapshots: Controls Maven’s download permissions for release and snapshot builds. Note the enabled child element. In this example, the value of Enabled is true to enable JBoss releases and the value of enabled is false to disable snapshots of JBoss releases. According to this configuration, Maven will only download release builds from the JBoss repository, not snapshot builds.
  • The default value indicates that the warehouse layout is the default for Maven2 and Maven3, not the Maven1 layout. The layout of Maven1 is rarely used.
  • Releases and snapshots contain two other child elements: updatePolicy and checksumPolicy.

1: The updatePolicy element is used to configure how often Maven checks for updates from remote repositories. The default value is Daily, indicating that Maven checks once a day. Other available values include: never- never checks for updates; Always – checks for updates every build; Interval: X- Checks for updates every X minutes (X is an arbitrary integer). The checksumPolicy element is used to configure Maven’s policy for checking checksum files. When a build is deployed to a Maven repository, the corresponding validation and files are deployed. Maven validates the checksum file when downloading the artifacts. If the checksum validation fails, Maven will output a warning message when executing the build when the checksumPolicy value is the default WARN. Other available values include: Fail-Maven will fail the build if the checksum error occurs; Ignore – Causes Maven to completely ignore checksum errors.

Authentication of the remote warehouse

Most remote repositories do not require authentication, but if you use them internally, you need to configure authentication information for security. Configuring authentication information is different from configuring the remote repository. The remote repository can be configured directly in pom.xml, but the authentication information must be configured in settings.xml. This is because THE POM tends to be committed to the repository for all members to access, whereas settings. XML generally exists only on the native. Therefore, it is more secure to configure authentication information in settings. XML.

<settings>2... 3<! -- Configure remote warehouse authentication information -->
 4     <servers>
 5         <server>
 6             <id>releases</id>
 7             <username>admin</username>
 8             <password>admin123</password>
 9         </server>
10     </servers>11... 12</settings>
Copy the code

This id must be the same as the remote repository ID you configured in pom.xml. It is this ID that links authentication information to the repository configuration.

Deploy artifacts to a remote repository

The purpose of building our own remote warehouse is to facilitate the deployment of our own project components and components that are not directly available from external warehouses. This can be used by other team members during development. In addition to compiling, testing, and packaging projects, Maven can also deploy project-generated artifacts to remote repositories. First, you need to edit the pom.xml file for your project. Configure the distributionManagement element as follows:

<distributionManagement>
        <repository>
            <id>releases</id>
            <name>public</name>
            <url>http://59.50.95.66:8081/nexus/content/repositories/releases</url>
        </repository>
        <snapshotRepository>
            <id>snapshots</id>
            <name>Snapshots</name>
            <url>http://59.50.95.66:8081/nexus/content/repositories/snapshots</url>
        </snapshotRepository>
</distributionManagement>
Copy the code

Repository represents a repository for the release version (stable version) of artifacts, and snapshotRepository represents a repository for the snapshot version (development test version). Both elements need to be configured with an ID, a name, and a URL, with the ID being the unique identifier of the remote repository, the name being readable, and the key URL representing the address of the repository.

Run the MVN clean deploy command, and Maven will deploy the project build output to the remote repository that corresponds to the configuration. If the current version of the project is the snapshot version, then to the snapshot version repository address, or otherwise to the release version repository address. Whether the current project is a snapshot or a release is distinguished by true. For those who forgot, look at the configuration of the remote warehouse above.

The mirror

If repository X can provide all the content stored in repository Y, then X can be considered a mirror of Y. Those who have used Maven know that foreign central warehouses are too slow to use, so it is necessary to choose a domestic image. I recommend the domestic Ali Cloud image. Ali Cloud image: The configuration is very simple, modify the conf folder Settings. XML file, add the following image configuration:

<mirrors>
    <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>        
    </mirror>
  </mirrors>
Copy the code

In the previous example, the value of central is central, indicating that the configuration is a mirror of the central repository and that any requests to the central repository will be forwarded to this mirror. Users can also configure the mirror of other repositories in the same way

Here are the various options for the

configuration

  • <mirrorOf>*<mirrorOf>: Matches all remote repositories.
  • <mirrorOf>external:*<mirrorOf>: matches all remote repositories except those using localhost, except those using the file:// protocol. That is, match all remote repositories that are not on the local machine.
  • <mirrorOf>repo1,repo2<mirrorOf>: Matches warehouses rePO1h and rePO2. Use commas (,) to separate multiple remote warehouses.
  • <mirrorOf>*,! repo1<mirrorOf>: matches all remote repositories except repo1, using an exclamation mark to exclude the repository from the match.

It should be noted that because the image repository completely blocks the mirrored repository, Maven will still have no access to the mirrored repository if the repository is unstable or out of service, and therefore will not be able to download artifacts.

Warehouse service search

Here are two places to search for warehouse services:

  • Sonatype Nexus:repository.sonatype.org/
  • MVNrepository:mvnrepository.com/

conclusion

So for the time being, then continue to add updates to this, about the private server construction of another open a presentation. This article is based on Maven Actual Combat. If you need e-books, you can follow the wechat official account: Tuye Java Super God School (java2Learn) reply with the keyword Maven to obtain e-books.