JavaRush /Java Blog /Random EN /Everything you wanted to know about Maven - "Java project...

Everything you wanted to know about Maven - "Java project from A to Z"

Published in the Random EN group
Hello everyone, dear friends. I would like to apologize right away: I remember that I promised that I would write an article once a week. Did not work out. I just haven’t gotten around to sitting down and writing properly, but I don’t want to do it this way or that. I won’t whine about the reasons, since I don’t need it, and you certainly aren’t interested. The project is not dead, it was in stasis :) We continue! And today’s material is dedicated to Maven. "Java project from A to Z": Everything you wanted to know about Maven - 1

Let's talk about Maven

First you need to install it. Of course, since I have a Mac, I can only show the installation for a Mac. It's just bad luck. I installed it a long time ago, so you'll have to do it yourself :)
Instructions for installing Maven are in this material .

Why do we need Maven?

Maven is a project build tool, along with Gradle and Ant. Just because I will be using it in JRTB (JavaRush Telegram Bot), I want to bring you up to date. Nowadays, not a single project is created without an assembly system, because it simplifies our life many times over. This allows:
  • • pull up all the necessary libraries (in terms of tools for assembly - dependencies (that is, dependency));
  • • determine exactly how the project needs to be assembled and into what (for example, do we want to collect it in WAR or JAR or executable JAR);
  • • set the project version in one place so that it is indicated during assembly;
  • • describe the project and its life cycle;
  • • add so-called plugins (traditional version of the English word Plugin);
  • • publish libraries in a shared repository so that other projects can pull them up as dependencies.
In general, he does a lot of things, and they are all useful. I will say this: for novice engineers it is not necessary to know all the functionality from cover to cover. Here, as with git, it is important to understand the basics and general concepts. This is what we will do. For us, Maven starts with an XML file in the root of our project called pom.xml . We will do everything in practice, so first we will create our first project in the JavaRush Community. To do everything wisely, I will use a template for the repository , where the basic things that I described once on JR are already configured . To create, go to the repository with the template and click the Use this template button : "Java project from A to Z": Everything you wanted to know about Maven - 2As a result, we have the first repository in our community :) We download the project locally. To do this, through the idea, go to File -> New -> Project from Version Control . In the window that appears, enter a link to the project on Github (the result will be better if everyone creates the same project separately and goes through all the steps with me): "Java project from A to Z": Everything you wanted to know about Maven - 3Click Clone , and the project is cloned .

pom.xml is the head of everything

Everything you need is in pom.xml. All information about the project, its developer and on which remote repository the project is stored. At the start, we are interested in the following blocks: <project/> - this is the main block, which contains all the information about the project. All others will be explicitly or transitively in it. Inside the opening tag it says something like this:
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://maven.apache.org/POM/4.0.0"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                     http://maven.apache.org/xsd/maven-4.0.0.xsd">
And on top of everything else, the next line is also written in all pomniks (the slang is supposedly from pom.xml :)).
<modelVersion>4.0.0</modelVersion>
But then it gets more interesting: we will describe how we identify the project that our memorial describes. Using my library as an example, I will describe it, and then we will add it to our memory, to the newly created project:
<groupId>com.github.romankh3</groupId>
<artifactId>image-comparison</artifactId>
<version>4.4.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Image Comparison</name>
The main thing here:
  • groupId is the identifier of the development organization or individual engineer. This is usually the domain in reverse order. As an example, the romankh3 account on Github is described here. It is very important. Let's say for the Spring ecosystem it is com.springframework . This way you can distinguish the original project from someone else's fork or simply by the coincidence of the project name.
  • artifaceId is already the name of a specific project that is described in this memory.
  • version —the version of this project. Everything here is clear as day: added new functionality, fixed old ones, refactored or made some other changes - increased the version.
  • packaging - here we describe how Maven should assemble our project. Either in Jar, or in War, or some others .
  • name - here is a more pleasing name for the project.
There are still some things that are not at all required to be filled in - Maven will work without them - but if you need to publish the library for public use, it’s definitely worth adding them. What are these things?
  • • path to the project repository, from where it can be downloaded

    <url>https://romankh3.github.io/image-comparison/</url>

  • • the license under which this project is distributed. Moreover, there may be more than one, and therefore you need to set it this way:

    <licenses>
     <license>
       <name>The Apache Software License, Version 2.0</name>
       <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
     </license>
    </licenses>

  • • information about the developers who created/are creating the project:

    <developers>
     <developer>
       <id>romankh3</id>
       <name>Roman Beskrovnyi</name>
       <email>roman.beskrovnyy@gmail.com</email>
     </developer>
    </developers>

  • • scm block, which describes how the project can be accessed:

    <scm>
    <connection>git@github.com:romankh3/image-comparison.git</connection>
    <developerConnection>git@github.com:romankh3/image-comparison.git</developerConnection>
     <url>https://github.com/romankh3/image-comparison</url>
    </scm>

After we have described the general information, we can add a block with dependencies:
<dependencies>
   <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
       <version>2.26.0</version>
       <scope>test</scope>
   </dependency>
   <dependency>
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter-api</artifactId>
       <version>5.5.2</version>
       <scope>test</scope>
   </dependency>
<dependency>
   	<groupId>com.github.romankh3</groupId>
   	<artifactId>image-comparison</artifactId>
   	<version>4.3.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Here I added two libraries for testing: they are always needed. As you may have already noticed, dependencies have a Scope - scope. In our case , test is specified , which means that we simply will not see this dependency in the main code. Next, to make everything look beautiful, you can use a separate tag to display the <properties/> versions :
<properties>
   <mockito.version>2.26.0</mockito.version>
   <junit.version>5.5.2</junit.version>
   <image.comparison.version>4.3.0</image.comparison.version>
</properties>
So the dependency block can be updated using the ${PROPERTY_NAME} construct :
<dependencies>
   <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
       <version>${mockito.version}</version>
       <scope>test</scope>
   </dependency>
   <dependency>
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter-api</artifactId>
       <version>${junit.version}</version>
       <scope>test</scope>
   </dependency>
   <dependency>
       <groupId>com.github.romankh3</groupId>
       <artifactId>image-comparison</artifactId>
       <version>${image.comparison.version}</version>
       <scope>test</scope>
   </dependency>
</dependencies>
Next comes a large <build/> block , which contains an important <plugins/> block , with which you can customize the build process. You can add one or more plugins inside the <plugins/> block , like this:
<build>
   <plugins>
       <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-source-plugin</artifactId>
           <version>3.2.0</version>
           <executions>
               <execution>
                   <id>attach-sources</id>
                   <goals>
                       <goal>jar</goal>
                   </goals>
               </execution>
           </executions>
       </plugin>
   </plugins>
</build>
Here you can see that I have added two plugins - maven-source-plugin and maven-javadoc-plugin . Each of the plugins has settings, attributes (parameters) that can be set, thereby customizing the plugins. This will be interesting for us in the future. For now, let's remember and move on. In the same way as for dependencies, we will put the plugin versions in <properties/> . Based on this, you can create the following memory:
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://maven.apache.org/POM/4.0.0"
        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.github.javarushcommunity</groupId>
   <artifactId>maven-demo</artifactId>
   <version>1.0-SNAPSHOT</version>
   <packaging>jar</packaging>

   <name>Maven Demo Project</name>

   <url>https://github.com/javarushcommunity/maven-demo/</url>

   <properties>
       <mockito.version>2.26.0</mockito.version>
       <junit.version>5.5.2</junit.version>
       <maven.compiler.source>1.8</maven.compiler.source>
       <maven.compiler.target>1.8</maven.compiler.target>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
       <source.plugin.version>3.2.0</source.plugin.version>
   </properties>

   <dependencies>
       <dependency>
           <groupId>org.mockito</groupId>
           <artifactId>mockito-core</artifactId>
           <version>${mockito.version}</version>
           <scope>test</scope>
       </dependency>
       <dependency>
           <groupId>org.junit.jupiter</groupId>
           <artifactId>junit-jupiter-api</artifactId>
           <version>${junit.version}</version>
           <scope>test</scope>
       </dependency>
   </dependencies>

   <build>
       <plugins>
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-source-plugin</artifactId>
               <version>${source.plugin.version}</version>
               <executions>
                   <execution>
                       <id>attach-sources</id>
                       <goals>
                           <goal>jar</goal>
                       </goals>
                   </execution>
               </executions>
           </plugin>
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-javadoc-plugin</artifactId>
               <version>${javadoc.plugin.version}</version>
               <executions>
                   <execution>
                       <id>attach-javadocs</id>
                       <goals>
                           <goal>jar</goal>
                       </goals>
                   </execution>
               </executions>
           </plugin>
       </plugins>
   </build>
</project>

Maven lifecycle

Maven has such a thing as maven lifecycle. It is worth saying that this is a set of tasks that a maven can perform. There may be other tasks besides maven lifecycle. What is it about? There is a set of commands with which you can assemble a project ( build ... again, of course, a tracing paper from English, but without this there’s nowhere), delete builds that Maven collected, install in Maven local so that you can locally pull up the project as a dependency, and so on. Now let's talk about everything in more detail. Before writing my opinion about these teams, I decided to read what they were writing on the Internet about this matter... and realized that it was very difficult to describe. For work, for initial work, we need several commands . Let's describe them:
  • compile — compile the project. This is the first stage: during it you can see if there are any compilation errors in the project. Sometimes there are various leapfrogs with working in IDEA, which is why compilation problems appear where they should not exist. So this command will dot all the i's.
  • test - runs all the tests that run on JUnit and are located where Maven expects them ( src/test/java is your captain).
  • package is the next command, which includes the two previous ones: that is, the compile command is first launched inside it, then the test command is sent to the compiled project , and if everything is ok here, the creation of an archive starts (the archive that we select in < packaging/>))
  • install - when we install Maven on a machine, we have a local Git repository that stores the libraries that we download for projects. But the beauty of Maven is that we can use the install command to add our project to the local Git repository and use our project locally as a dependency. Don't believe me? Try it :) This way you can quickly see how your project will look like a dependency on another.
  • deploy is the crown of everything that came before. A command that gives the ability to add a project not only to a local repository as install, but also to a remote one, from where everyone with access can use it as a dependency.
  • verify - a command that will check everything and tell whether the project is ready for deployment.
  • clean - of course, the compiled files and archive must be stored somewhere. Maven has a target folder for this . This is data that the project does not need. And before reassembling the project, it would be good to delete everything that came before. This is what the clean command is for .

Maven Plugins

I wanted to talk more about plugins, but the article is already long. This will be your homework. Understand what it is and how to use it. In the continuation of the article, we will deal with Maven in practice.

A list of all materials in the series is at the beginning of this article.

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION