A few days ago in a technical group, someone was asking what the keywords groupId, artifactId, and version mean in Maven, so I thought it would be worthwhile to talk about these core concepts in Maven.

Success is not in the future, but from the moment you decide to do, continue to accumulate.

Today we will look at the core concepts in Maven. With these core concepts in mind, we can learn and use Maven in more depth later.

coordinates

Concept of coordinates

From Baidu Encyclopedia

A number or group of numbers capable of determining the position of a point in space, called the coordinates of the point. It is usually expressed by the distance from this point to a number of fixed straight lines that intersect vertically. These lines are called coordinate axes. The number of axes is 2 (x,y) in the plane and 3(x,y,z) in space.

It’s a way of identifying a single point in a plane or a single point in a space.

Coordinates in Maven

One of Maven’s core roles is to manage project dependencies, importing the various JARS we need, and so on. In order to automate the parsing of any Java artifact, Maven must uniquely identify these JARS or other resources, which are the basis for managing project dependencies, known as coordinates. Projects, including our own, are also uniquely identified by coordinates so that they can be referenced by dependencies in other projects.

case

Dependency: For example, we rely on the junit JAR package.

<! -- pom. XML - >
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>3.8.1</version>
  <scope>test</scope>
</dependency>
Copy the code

Define our project as a JAR or WAR package in the project.


      
<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.tian</groupId>
        <artifactId>maven-demo</artifactId>
        <version>1.0 the SNAPSHOT</version>
        <! -- default is jar -->
        <packaging>jar</packaging>
</project>
Copy the code

The form of the last jar or war typed:

artifactid-version.jar
artifactid-version.war
Copy the code

The packaging tag is jar by default, so it usually ends up being a JAR without specifying a JAR or war.

Composition of Maven coordinates

** “groupId” ** Organization identifier (package name). Defines the actual project to which the current Maven project belongs. First, Maven projects and actual projects don’t necessarily have a one-to-one relationship. For example, the actual project of Spring Framework, there are many Maven projects corresponding to it, such as Spring-core, spring-Context, etc. This is due to the concept of modules in Maven, so an actual project is often divided into many modules. Second, groupId should not correspond to the organization or company the project belongs to. The reason is simple: there are many actual projects in an organization. If groupId is defined only at the organization level, and artifactId can only define Maven projects (modules), as we will see later, then the actual project level will be difficult to define. Finally, groupId is represented similarly to Java package names, usually in reverse one-to-one correspondence with domain names. In the example above, the groupId is junit, which is ok, because there is only one junit in the world, and it does not have many branches.

** “artifactId” ** Project name. This element defines a Maven project (module) in the current actual project. It is recommended to prefix the artifactId with the actual project name. In the example above, junit is the actual project name, convenient and intuitive. By default, maven generates artifacts with an artifactId header, such as Junit-3.8.1.jar, prefixed with the actual project name to easily locate artifacts from the local repository.

** “version” ** The current version of the project or the version of the JAR we are relying on. This element defines the version of the artifact to use. In the example above, junit is 3.8.1, or you can change it to 4.0 to indicate that junit is 4.0.

The most common packaging methods for a project are JAR and WAR. The default is JAR. Define how Maven projects are packaged and what packages of artifacts are used. First, the packaging method usually corresponds to the file extension of the generated component. If there is no packaging in the preceding example, the package is jar by default, and the final file name is junit-3.8.1.jar. It can also be packaged as a WAR, etc.

“Classifier” This element is used to help define some attachments for the build output. The accessory component corresponds to the main component, such as junit-3.8.1.jar in the example above. The project may also generate some plug-ins such as Junit-3.8.1-javadoc. jar,junit-3.8.1-sources.jar, so that the accessory component has its own unique coordinates.

Among the five elements, groupId, artifactId, and Version must be defined. Packaging is optional (jar is the default value), while classfier cannot be defined directly and must be used together with plug-ins.

Why does Maven use coordinates?

  • With so many builds in the Maven world, we need to find a unified specification that uniquely identifies a build.
  • With a uniform specification, you can leave the search to machines.

Maven dependency Management

Rely on

Dependence is usually expressed as: I need what you have, just like mutual dependence between lovers, mutual dependence between husband and wife, dependence on water, dependence on food and so on.

In Maven, the project relies on THE B.jar package for every class that is used in the project.

Complex point relationships are multi-layer dependencies: a.jar depends on B. jar, and possibly B. jar depends on C. jar. This phenomenon can also be called dependency transitivity.

Our project relies indirectly on B. Jar.

Depend on the configuration

Maven dependency configuration examples are as follows:

<! -- Add dependency configuration -->
<dependencies>
  <! Add junit jar dependencies here -->
  <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.9</version>
      <scope>test</scope>
  </dependency>
  <! Hello jar dependency = jar dependency = jar dependency = jar dependency
  <dependency>
      <groupId>com.tian.maven</groupId>
      <artifactId>user-service</artifactId>
      <version>0.0.1 - the SNAPSHOT</version>
      <scope>compile</scope><! -- Dependency scope -->
  </dependency>
</dependencies>
Copy the code

Depend on the range

The dependency scope refers to the jar on which we need to rely. Some are needed at compile time, some are needed at test time, etc.

There are six dependent scopes:

“Compile” is the default compile dependency scope. This works for compilation, testing, and running all three classpath. That is, the dependent JAR package is used at compile, test, and run time;

** “test” ** Test dependency scope. This is only valid for test CLASspath. Such dependencies cannot be used when compiling and running a project, typically JUnit, which is only needed when compiling and running test code;

** “provided” ** already provides the scope of dependency. The classpath of the test is valid for compilation, but not for run. Because it is already provided by the container, such as servlet-api.jar, it is needed at compile and test time, but at run time it is already provided by the Web container and maven is not needed to help introduce it.

Maven dependencies that use this scope are valid for compiling tests, running tests, and the classpath that runs the project, but not for compiling main code, such as JDBC driver implementations, which require specific JDBC driver implementations at runtime.

** “system” ** System dependencies. Using system-scoped dependencies must explicitly specify the path of the dependency file via the systemPath element, does not rely on Maven repository resolution, and may cause the build to be non-portable (i.e. it may work on your computer). Provided (on your computer) provided (on your computer)

<systemPath>${java.home}/lib/rt.jar</systemPath>
Copy the code

** “import” ** Only POM supports this scope on type dependencies in this section. It indicates that the dependency will be replaced with a list of valid dependencies in the specified POM section. Because they have been replaced, dependency imports of scope do not actually participate in limiting dependency transitivity, and are used more often in springboot and springcloud.

Compile, test, Runtime, and Provided are commonly used.

Dependency scopes not only control relationships with the three classpath types, but also affect transitive dependencies, as shown below:

** “Note” ** This is expected to be run-time scoped, so all compile dependencies must be explicitly listed. However, if the library you depend on extends a class from another library, both must be available at compile time. Therefore, even though compile time dependencies are transitive, they remain in compile scope.

Maven Repository Management

Maven repositories

The repository is used to store all Maven shared builds in a unified location. In other words, it is used to store jar packages. There is no jar package that can not be compiled locally every time.

Maven Repository Layout

Define the unique storage path for each build in the repository according to Maven coordinates, roughly as follows:

groupId/artifactId/version/artifactId-version.packaging

Local repository

In the previous article, there was only one local repository per user, in ~/.m2/repository/ by default, where ~ represents the user directory. In order to facilitate management, they usually make their own directory, specifically used to store local warehouse content. This way, when we develop, we will directly go to our local repository repository to find the jar, if not, we will pull it from the central repository.

The central warehouse

Maven’s default remote repository, URL: search.maven.org/. For example, when we were developing ali’s warehouse, maven.aliyun.com was used by many people for network reasons.

At this time, the relationship between our local warehouse and the central warehouse:

Private servers

Most companies build private servers. A private server is a special kind of remote warehouse that is set up on a local area network. For example, the company builds a local area network, the company also makes a warehouse, and then the developers directly use the company to build the private service on the line, which greatly reduces the network overhead and development costs (sometimes the external network access is very slow, will waste everyone’s development time).

This allows developers to pull each JAR package directly from the company’s private server each time they need it, instead of having to use the Internet to pull it from a central repository. In short, saving time and saving network starts. And some enterprises still do not give the net, at this time you know the importance of this private service.

With private server added, the relationship between local warehouse + private server + central warehouse:

In the interview, I was frequently asked: what is the relationship between local warehouse, private server and central warehouse?

Maven Life Cycle

Maven’s life cycle: From our project build to project release.

Description of each stage:

To complete the Default life cycle, these phases (including other life cycle phases not listed above) are executed sequentially.

Maven has three standard life cycles:

  • Clean Lifecycle does some cleaning prior to the actual build.
  • Core parts of a Default Lifecycle build, compile, test, package, deploy, etc.
  • Site Lifecycle generates project reports, sites, and release sites.

These three criteria are independent of each other, you can just call clean to clean up the working directory, and just call site to generate the site. Of course, you can run all three life cycles directly by running the MVN Clean Install site.

When any phase is run, all the preceding phases are run, which is why when we run MVN Install, the code is compiled, tested, and packaged. Furthermore, Maven’s plug-in mechanism is completely dependent on Maven’s life cycle, so understanding the life cycle is critical.

Maven plug-in

Maven does nothing, but specifies the stages and steps of the life cycle, which are done by plug-ins integrated into Maven.

  1. At its core, Maven defines only an abstract lifecycle, with specific tasks handed over to plug-ins.
  2. Each plug-in can implement multiple functions, and each function is a plug-in goal.
  3. Maven’s life cycle is bound to a plug-in target to complete a specific build task. For example, COMPILE is a plug-in target for the maven-Compiler-plugin.

This is a brief overview of plugins, and a future article will be devoted to Maven plugins.

Exclusion does not need to be relied upon

<dependency>
    <groupId>com.tian.maven</groupId>
    <artifactId>my-maven</artifactId>
    <version>1.0.0</version>
    <exclusions>
        <exclusion>
            <groupId>com.tian.maven</groupId>
            <artifactId>your-maven</artifactId>
        </exclusion>
    </exclusions>
</dependency>
Copy the code

The above exclusions element allows my-maven->your-maven dependencies to be passed on, i.e. my-maven->your-maven cannot be passed on to the current project.

Exclusions can have multiple exclusion elements, which can exclude one or more dependent passes. Only groupId and artifactId are required to declare exclusion, and version can be omitted.

conclusion

This article covers Maven coordinates, Maven dependency management, Maven repository management, Maven lifecycle, and a brief introduction to Maven plug-ins. With these concepts as a foundation, we can take a deeper look at why we use them in the studio.

“Don’t be afraid of the distance as long as the road is right.”