The brightest star in the night sky, 2018 please light me forward ~ Maven is our daily development will be used, the first day of the new year, the basic concepts of Maven that I have read to do the organization, as a primer and access to use.

 Maven Concepts


Maven as a build tool , not only to help us automate the build , but also able to abstract the build process , to provide build task implementation ; it cross-platform , the external provides a consistent operating interface , all this is enough to make it become an excellent , popular build tool .


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

 Installation of maven


A: Because I am window system, so here is only window how to install, in the installation of Maven before, make sure you have installed the JDK.


Two: Then go to the Maven download interface to download the desired version of the official website to unzip it into the directory you want.


Third: Finally set up the environment variables, the Maven installation configuration to the operating system environment, mainly to configure the M2_HOME and PATH two, such as Figure


Once you’ve done that, verify that you’ve done it by opening doc and typing in mvn -v and you’ll get the following message, which means you’ve done it successfully

 maven directory


  • bin directory: This directory contains the scripts that mvn runs to configure the java commands, prepare the classpath and related Java system properties, and then execute the Java commands.

  • boot directory: This directory contains only one file, plexus-classworlds-2.5.2.jar. plexus-classworlds is a class loader framework that provides a richer syntax for easier configuration than the default java class loader, which Maven uses to load its own libraries.

  • conf directory: This directory contains a very important file, settings.xml, which you can modify directly to customize Maven’s behavior globally on your machine. In general, we prefer to copy this file to the ~/.m2/ directory (where ~ is the user’s directory), and then modify this file to customize Maven’s behavior at the user’s level.

  • lib directory: This directory contains all the Maven runtime Java libraries , Maven itself is developed in modules , so the user can see such as maven-core-3.0.jar, maven-model-3.0.jar and so on, in addition to some of the third-party dependencies used by Maven contained here , such as commons -cli-1.2.jar, commons-lang-2.6.jar and so on.

 Maven commands


  • mvn clean: means run the clean operation (it will clean up the data in the target folder by default).

  • mvn clean compile: means run clean first and then run compile, it will compile the code into the target folder.
  •  mvn clean test: Run the cleanup and test.

  • mvn clean package: run clean and package.

  • mvn clean install: running clean and install will install the typed package into the local repository so that other projects can call it.

  • mvn clean deploy: run clean and deploy (publish to the top of the private service).


Most of the above commands are hyphenated, you can also be split up and executed separately, which is live, depending on personal preferences as well as the use of demand, Eclipse Run as maven project will provide commonly used commands.

 Setting up the http proxy


Editing the seeting.xml file Sometimes your company requires you to use a securely authenticated proxy to access the Internet for security reasons. In this case, you need to configure an HTTP proxy for Maven in order for it to properly access external repositories in order to download the resources you need. First make sure that you don’t have direct access to the public maven central repository. You can check the network by running the command ping repo1.maven.org directly. If you really need a proxy, first check that the proxy server is clear. For example, now there is a proxy service with IP address 218.14.227.197 and port 3128, we can run telnet 218.14.227.197 3128 to check if the port is open at that address. If you get an error message, you need to get the correct proxy service information first. If the telnet connection is correct, type ctrl+], then q, enter, and exit.


After checking this, edit the ~/.m2/settings.xml file (or copy $M2_HOME/conf/settings.xml if you don’t have that file). Add the proxy 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> 


This configuration is very simple, there can be more than one proxy element under proxies, if more than one proxy element is declared, by default the first activated proxy will take effect. Here, a proxy with id my-proxy is declared, the value of active is true to activate the proxy, and protocol indicates the proxy protocol to be used, which in this case is http. Of course, the most important thing is to specify the correct host name (host element) and port (port element). The above xml configuration comments out the username, password, and nonProxyHosts elements. When the proxy service requires authentication, you need to configure username and password. nonProxyHost element is used to specify which hosts do not need to be proxied, and you can use the “|” symbol to separate multiple hostnames. The configuration also supports wildcards, such as :*.google.com to indicate that all domains ending in google.com should not be accessed through the proxy.

 Maven plugin installation, based on IDEA


The blogger is now using IDEA to develop, so here is how to configure IDEA to introduce our above downloaded Maven

 Maven Usage

<?xml version="1.0" encoding="UTF-8"?>
<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-SNAPSHOT</version>
    <name>springBootDemo1</name>
</project>


The first line of the code is an XML header that specifies the version and encoding of this xml document. project is the root element of all pom.xml, it also declares some POM related namespaces and xsd elements. The first child element under the root element, modelVersion, specifies the current version of the POM model, which can only be 4.0.0 for Maven 3. The most important elements in the code are groupId, artifactId and version. These three elements define the basic coordinates of a project , in the Maven world , any jar, pom or jar are based on these basic coordinates to distinguish .


groupId defines which group the project belongs to, and is named arbitrarily, for example, Google’s myapp project is named com.google.myapp.


artifactId defines the unique ID of the current Maven project in the group, for example, define hello-world.


version specifies the current version of the project 0.0.1-SNAPSHOT, SNAPSHOT means snapshot, that the project is still under development, is not stable.


The name element provides a more user-friendly project name. Although it is not required, it is recommended that name be declared for each POM to facilitate the exchange of information.

 Dependent Configuration


The dependencies under the root element project 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: since the basic coordinates, for any dependency, the basic coordinates are the most important, Maven according to the coordinates in order to find the required dependencies.

  • type: the type of the dependency, for packaging defined by the project coordinates, in most cases this element does not need to be declared and defaults to jar.
  •  scope:scope of the dependency
  •  optional:Marks dependencies as optional.
  •  exclusions: used to exclude transitive dependencies

 Scope of reliance


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


  • **compile:** compiles the dependency scope. If not specified, this dependency scope is used by default. Maven dependencies that use this dependency scope are valid for all three classpaths: compile, test, and run. A typical example is spring-code, which needs to be used when compiling, testing and running.

  • test: Tests the dependency scope. Maven dependencies that use a sub-scope of dependencies are only valid for the test classpath and will not be used when compiling the main code or running the project. A typical example is Jnuit, which is only needed when compiling test code and running tests.

  • **provided:** A dependency scope has been 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 to compile and test the project, but is not required to be reintroduced by Maven at runtime because it is provided by the container.

  • **runtime:** runtime dependency scope. Maven dependencies that use this dependency scope are valid for testing and running the classpath, but not for compiling the main code. Typical example is the JDBC driver implementation, the compilation of the main code of the project only needs the JDBC interface provided by the JDK, only in the execution of the test or run the project need to implement the above interface specific JDBC driver.

  • **system:** system-scoped dependency. The relationship of this dependency to the three classpaths is identical to the provided dependency scope, however, the path to the dependency file must be explicitly specified via the systemPath element when using a system-scoped dependency. Since such dependencies are not parsed through the Maven repository and are often bound to the native system, they may constitute a non-portability of the build and should be used with caution. the systemPath element can refer to 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>

  • **import:** imports the dependency scope. This dependency scope has no real effect on the three classpaths. The relationship between the above dependency scopes other than import and the three classpaths is as follows.

 transferential dependence


For example, an account-email project for example, account-email has a compile-scoped dependency on spring-code, spring-code has a compile-scoped dependency on commons-logging, then commons-logging becomes the a compile-scoped dependency of account-email, and commons-logging is a pass-through dependency of account-email. 


With the pass-through dependency mechanism, you don’t have to think about what Spring Framework depends on when using it, and you don’t have to worry about introducing redundant dependencies.Maven parses the POMs of the direct dependencies, and introduces those necessary indirect dependencies into the current project in the form of pass-through dependencies.

 Scope of reliance


Assuming that A is dependent on B and B is dependent on C, we say that A is the first direct dependency on B, B is the second direct dependency on C, and A is the transitive dependency on C. The range of first direct dependency and second direct dependency determines the range of transitive dependency. The scope of the first and second direct dependency determines the scope of the transitive dependency, as shown in the following figure, the leftmost row indicates the scope of the first direct dependency, the top row indicates the scope of the second direct dependency, and the intersecting cells in the middle indicate the scope of the transitive dependency.

 From the chart above, we can notice this pattern:


  • 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 will not be passed;

  • When the scope of the second direct dependency is provided, pass only the dependencies whose scope of the first direct dependency is also provided, and cut pass the dependencies whose scope is also provided; the

  • When the scope of the second direct dependency is runtime, the scope of the pass-through dependency is the same as the scope of the first direct dependency, but compile is listed outside of it, when the scope of the pass-through dependency is runtime.


## Dependency Mediation Sometimes, when a transitive dependency causes a problem, you need to know exactly which dependency path the transitive dependency was introduced from. This is the role of dependency mediation. There are two major principles of dependency mediation: 1. Path closest takes precedence For example, if a project has a dependency on A: A->B->C->X(1.0), A->D->X(2.0), X is a transitive dependency on A. However, there are two versions of X on the two dependency paths, so according to the first principle, A->D->X(2.0) is a shorter path so that X() will be resolved and used 2. 2.0) will be resolved and used 2. first declarant takes precedence The first principle doesn’t work if the paths are all the same length, e.g., A->B->Y(1.0), A->C->Y(2.0),Y(1.0) and Y(2.0) have the same paths, so then according to the second principle, the one that is declared first is resolved.

 ## Optional dependencies


As shown in the figure, in the project A depends on B and B depends on X and Y. If the scope of all these three is compile then X and Y are the pass-through dependencies for the scope of A’s compile but if I want X,Y not to be used as a pass-through dependency for A, I don’t give it to him. Then I need to configure optional dependencies as 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>  

 Configuration is also simple, add the

<optional>true</optional>


This means that the dependency is optional, so that if A wants to use X,Y, it will have to add the dependency directly to the display.

 exclude dependencies


Sometimes you introduce dependencies contain dependency packages you do not want, you want to introduce their own want, this time you have to use the exclusion of dependencies, such as the following figure spring-boot-starter-web comes with the logback log package, I want to introduce the log4j2, so I first exclude the logback dependencies, and then the introduction of the packages you want on the line!

 Exclude dependent code structures:

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


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

 Categorization dependency


Sometimes we introduce a lot of dependent packages, they all come from different modules of the same project, so they all have the same version number, this time we can use the attribute to unify the management of version numbers

<project>  
    <modelVersion>4.0.0</modelVersion>  
    <groupId>com.juven.mvnbook.account</groupId>  
    <artifactId>accout-email</artifactId>  
    <version>1.0.0-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>  

 As shown in the figure, it is first passed through the

</properties>
    ...
</properties>


to define, and then rely on the use of ${} below to introduce your properties.


This section introduces the concepts of repositories such as origin, layout, categorization, configuration, internal working mechanism, mirroring, etc.

 Origin of the Warehouse


In the Maven world, any dependency, plugin, or output of a project build can be called a building block. Thanks to the coordinate mechanism, any Maven project uses any of the artifacts in exactly the same way. On this basis, Maven can store the artifacts shared by all Maven projects in a unified location, and this unified location is the repository.


Instead of storing their dependencies individually, actual Maven projects will simply declare the coordinates of those dependencies, and when needed (e.g., when compiling a project that needs to add the dependencies to the classpath), Maven will automatically find the repository artifacts based on the coordinates and use them.


To enable reuse, the artifacts that can be generated after the project is built can also be installed or deployed to the repository for use in other projects.

 Layout of the warehouse


Any component has its own coordinates, according to which you can define its unique storage path in the repository, which is Maven’s repository layout. The path and coordinates correspond to groupId/artifactId/version/artifactId-version.packaging. For example, the following paging plugin depends on the following:

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

 Then the path to his corresponding repository is this:


The Maven repository is based on a simple file system, and we understand how it is stored, so when you encounter some problems with the repository, it is easy to find the relevant files and locate the problem.

 Classification of warehouses

 local warehouse


In general, there is no directory such as lib/ in the Maven project directory for storing dependency files. If Maven needs to use a dependency file when performing compilation or testing, it always uses the dependency file from the local repository based on the coordinates.


By default, on both Window and Linux, each user has a repository directory with the path name .m2/repository/ in their user directory. If you want to customize the local repository directory address. You can edit the file ~/.m2/settings.xml and set the value of the localRepository element to the desired repository address, for example.

<settings>
<localRepository>D:\java\repository\</localRepository>
</settings>


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

 Remote warehouse — centralized warehouse


Since the original local repository is empty, Maven must know of at least one available remote repository in order to download the needed building blocks when executing Maven commands. The central repository is such a default remote repository, and the Maven installation file comes with the configuration for the central repository.


The central repository contains most of the world’s popular open source Java components , as well as source code , author information , SCM, information , license information , etc., every month here will accept the world’s Java programmers about 100 million visits , its contribution to the world’s Java developers can be seen .

 Remote Warehouse – Private Service


A private service is a special kind of remote repository, which is a repository service set up on a LAN. The private service proxies the remote repository on the WAN for Maven users on the LAN. When Maven needs to download a component, it requests it from the private service, and if the component does not exist on the private service, it downloads it from an external remote repository, caches it on the private service, and then serves the Maven download request. As a result, some components that cannot be downloaded from external repositories can be uploaded locally to the private service for everyone to use. Benefits of private services:

  •  Save yourself the speed of the extranet
  •  Accelerating Maven builds
  •  Deploying third-party builds
  •  Improved stability and control
  •  Reducing the load on the central warehouse

 Configuration of the remote repository


In the usual development, we often do not use the default central repository, the default central repository access is slow, access to the people may be a lot of people, and sometimes can not meet the needs of our project, the project may require some of the building blocks of the central repository is not available in other remote repositories, such as JBoss Maven repository. At this point, you can configure the warehouse in pom.xml, the code is as follows:


    <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>

  • **repository:** Under the repositories element, one or more remote repositories can be declared using the repository sub-element.

  • **id: ** the unique id of the repository statement, in particular, it should be noted that Maven comes with a central repository using the id of central, if the other repository statement also uses this id, it will override the central repository configuration.

  • **name: ** the name of the warehouse, so that we intuitively easy to know which warehouse is which, for the time being, did not find other great meaning.

  • **url:** points to the address of the repository, in general, the address is based on the http protocol, Maven users can open the repository address in the browser to browse the components.

  • releases and snapshots: These are used to control Maven’s download permissions for release and snapshot artifacts. Note the enabled sub-element. In this example, the value of enabled for releases is true, which means that the JBoss repository is enabled to download releases, while the value of enabled for snapshots is false, which means that the JBoss repository is disabled to download snapshots. According to this configuration, Maven will only download the release version of the artifacts from the JBoss repository, but not the snapshot version of the artifacts.

  • **layout:** The element value default indicates that the repository layout is the default layout for Maven2 and Maven3, not Maven1. Basically, the Maven1 layout will not be used.

  • Other: for releases and snapshots, in addition to enabled, they contain two other sub-elements updatePolicy and checksumPolicy.

      1: Elements
    updatePolicy

    Used to configure how often Maven checks for updates from remote repositories. The default value is daily, which means Maven checks for updates 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 any integer).


    2: The element checksumPolicy is used to configure the Maven policy for checking checksum files. When a build is deployed to a Maven repository, the corresponding checksum file is deployed at the same time. Maven will validate the checksum file when downloading the component. 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 encounters a checksum error and lets the build fail; ignore-Maven ignores the checksum errors; ignore-so that Maven completely ignores checksum errors.

 Authentication of remote repositories


Most remote repositories do not require authentication, but if you are using it internally, you still need to configure authentication information for security reasons. Configuring authentication information is different from configuring a remote repository, which can be configured directly in the pom.xml, but authentication information must be configured in the settings.xml file. This is because pom is often committed to a code repository for all members to access, while settings.xml generally only exists locally. Therefore, it is safer to configure authentication information in settings.xml.

<settings>
  2     ...
  4     <servers>
 5         <server>
 6             <id>releases</id>
 7             <username>admin</username>
 8             <password>admin123</password>
 9         </server>
10     </servers>
11     ...
12 </settings>


Here in addition to configure the account password, the value of the key is the id, this id should be configured with you in the pom.xml inside the remote repository repository id consistent, it is the id of the authentication information with the repository configuration linked together.

 Deploy components to remote repositories


The purpose of building our own remote repositories is to make it easier to deploy our own project artifacts, as well as some artifacts that are not directly available from external repositories. This is so that it can be used by other team members during development. In addition to compiling, testing, and packaging the project, Maven can also deploy the components generated by the project to a remote repository. First, you need to edit the project’s pom.xml file. Configure the distributionManagement element with the following code:

<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>


Looking at the code, you can see the difference from the naming, repository indicates the repository that represents the release version (stable version) of the artifacts, and snapshotRepository indicates the repository that represents the snapshot version (development test version). Both elements need to be configured id, name and url, id for the unique identification of the remote repository, name is to facilitate people to read, the key url that the address of the warehouse.


Configured to run the command mvn clean deploy, Maven will be the project build output components deployed to the configuration of the corresponding remote repository, if the current version of the project is a snapshot version, then deployed to the snapshot version of the repository address, otherwise it will be deployed to the release version of the repository address. If the current version of the project is a snapshot version, it will be deployed to the snapshot version repository address, otherwise it will be deployed to the release version repository address. If you forgot to do this, look at the ## remote repository configuration above.


If the repository X can provide all the content stored in the warehouse Y, then it can be considered that X is a mirror of Y. If you have used Maven, you know that the foreign central repository is too much to use. Used Maven know, foreign centralized repository is too slow to use, so choose a domestic mirror is necessary, I recommend the domestic Aliyun mirror. Ali cloud mirror: configuration is very simple, modify the conf folder under the settings.xml file, add the following mirror 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>


In the example above, the value of central, means that the configuration for the central repository of the mirror, any request for the central repository will go to the mirror, the user can also use the same method to configure other repositories of the mirror

 Here’s a description of the various options for the <mirrorOf> configuration

  •   <mirrorOf>*<mirrorOf> : Match all remote repositories.

  • <mirrorOf>external:*<mirrorOf> : Match all remote repositories, except those using localhost, and except those using file:// protocol. That is, match all remote repositories that are not on the local machine.

  • <mirrorOf>repo1,repo2<mirrorOf> : Match repositories repo1h and repo2, using commas to separate multiple remote repositories.

  • <mirrorOf>*,!repo1<mirrorOf> : Match all remote repositories except repo1, use exclamation point to exclude repositories from matching.


Note that because the mirrored repository completely blocks the mirrored repository, when the mirrored repository is unstable or out of service, Maven will still not be able to access the mirrored repository, and thus will not be able to download components.


For the time being, we will continue to add and update this article, and we will open another piece of information about the construction of the private service. This is based on the “Maven battle” organized and refined. The need for e-book partners can pay attention to the blogger WeChat public number: java java2Learn (java2Learn) Reply to the keyword maven to get the e-book.

By lzz

Leave a Reply

Your email address will not be published. Required fields are marked *