1.1 List of plugins to build in Maven

The assembly in Maven can be configured very flexibly. Maven developers have specially created dozens of plugins, using which you can very flexibly customize various assemblies. The most popular of them are shown in the table below:

plugin Description
1 maven-compiler-plugin Manages Java compilation
2 maven-resources-plugin Controls the inclusion of resources in an assembly
3 maven source plugin Controls whether source code is included in an assembly
4 maven-dependency-plugin Controls the process of copying dependency libraries
5 maven-jar-plugin Plugin for creating final jar file
6 maven war plugin Plugin for creating the final war file
7 maven-surefire-plugin Manages test runs
8 buildnumber-maven-plugin Generates a build number

Each plugin is interesting in its own way, but we will have to analyze them all. Let's start with the main thing - the compilation management plugin.

1.2 Compilation plugin maven-compiler-plugin

The most popular plugin that allows you to control the version of the compiler and is used in almost all projects is the maven-compiler-plugin. It has default settings, but in almost every project they need to be set again.

In the simplest version, in the plug-in, you need to specify the version of the Java source code and the version of the Java machine under which the assembly is carried out:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.2</version>
    <configuration>
        <source>1.11</source>
        <target>1.13</target>
        <encoding>UTF-8</encoding>
    </configuration>
</plugin>

In the example above, we set three Java compiler options: source, targetand encoding.

The parameter sourceallows us to set the Java version for our sources. The parameter targetis the version of the Java machine under which you want to compile the classes. If no code or Java machine version is specified, then the default is 1.3

Finally, the parameter encodingallows you to specify the encoding of Java files. We indicated UTF-8. Now almost all sources are stored in UTF-8. But if this parameter is not specified, then the current encoding of the operating system will be selected. For Windows, this is the encoding Windows-1251.

There are also cases when the build computer has several versions of Java installed: to build different modules and/or different projects. In this case, JAVA_HOMEonly the path to one of them can be specified in the variable.

In addition, there are different implementations of the Java machine: OpenJDK, OracleJDK, Amazon JDK. And the larger the project, the more complex its structure. But you can explicitly set the path to the javac compiler for the plugin using the tag . It was added specifically for this occasion.

The plugin maven-compiler-pluginhas two goals:

  • compiler:compile– compilation of sources, by default associated with the compile phase
  • compiler:testCompile– compilation of tests, by default it is associated with the test-compile phase.

You can also specify a list of arguments to be passed to the javac compiler on the command line:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.2</version>
    <configuration>
        <compilerArgs>
            <arg>-verbose</arg>
            <arg>-Xlint:all,-options,-path<arg>
        </compilerArgs>
    </configuration>
</plugin>

1.3 Plugin for creating jar file maven-jar-plugin

If you want to build your own jar library with Maven, you will need the maven-jar-plugin. This plugin does a lot of useful things.

An example of such a plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <includes>
            <include>**/properties/*</include>
        </includes>
        <archive>
           <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
        </archive>
    </configuration>
</plugin>

First, it can be used to specify which files will go into the library and which will not. Using tags <include>in the section, <includes>you can specify a list of directories whose content needs to be added to the library .

Secondly, each jar must have a manifest ( MANIFEST.MF file ). The plugin itself will put it in the right place in the library, you just need to specify which path to take it. The tag is used for this <manifestFile>.

Finally, the plugin can generate a manifest on its own. To do this, instead of a tag, <manifestFile>you need to add a tag <manifest>and specify data for the future manifest in it. Example:

<configuration>
    <archive>
        <manifest>
            <addClasspath>true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
            <mainClass>com.codegym.MainApplication</mainClass>
        </manifest>
    </archive>
</configuration>

The tag <addClasspath>specifies whether to add to the manifest CLASSPATH.

The tag <classpathPrefix>allows you to add a prefix (in the example lib) before each resource. Specifying a prefix in <classpathPrefix>allows you to place dependencies in a separate folder.

Yes, you can place libraries inside another library. And there are many surprises waiting for you when you need to pass the path to the properties file somewhere, which is in the jar library, which is in the jar library.

Finally, the tag <mainClass>points to the main executable class. “What is the main executable class? ", - you ask. And the thing is that a Java machine can run a program that is specified not only by a Java class, but also by a jar file. And it is for this case that the main starting class is needed.

1.4 Build number generation plugin buildnumber-maven-plugin

Very often, jar libraries and war files include information with the name of the project and its version, as well as the version of the assembly. Not only is this useful for managing dependencies, but it also simplifies testing: it is clear in which version of the library the error is fixed and in which it is added.

Most often, this task is solved like this - they create a special file application.propertiesthat contains all the necessary information and include it in the assembly. You can also configure the build script so that the data from this file migrates to MANIFEST.MFetc.

But what is most interesting is that Maven has a special plugin that can generate such an application.properties file. To do this, you need to create such a file and fill it with special data templates. Example:

# application.properties
app.name=${pom.name}
app.version=${pom.version}
app.build=${buildNumber}

The values ​​of all three parameters will be substituted at the build stage.

Parameters pom.nameand pom.versionwill be taken directly from pom.xml. And to generate a unique build number in Maven, there is a special plugin - buildnumber-maven-plugin. See example below:

<packaging>war</packaging>
<version>1.0</version>
<plugins>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>buildnumber-maven-plugin</artifactId>
        <version>1.2</version>
        <executions>
            <execution>
                <phase>validate</phase>
                <goals>
                    <goal>create</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <revisionOnScmFailure>true</revisionOnScmFailure>
            <format>{0}-{1,date,yyyyMMdd}</format>
            <items>
                 <item>${project.version}</item>
                 <item>timestamp</item>
            </items>
        </configuration>
    </plugin>
</plugins>

In the example above, three important things happen. First, the plugin itself is specified for setting the assembly version . Secondly, it is specified that it will run during the validate phase (the very first phase) and generate a build number - ${buildNumber}.

And thirdly, the format of this assembly number is indicated, which is glued together from several parts . This is the version of the project project.versionand the current time given by the template. The template format is specified by the Java class MessageFormat.