The result of a Maven build process is an artifact. Each artifact is defined by its identifier, its group, and its version. This is crucial when working with Maven, because every dependency you'll use will need to be identified by these three mentioned properties.
The idea behind Maven is quite simple—you create a project structure that looks something like this:
You can see that the code is placed in the src
folder—the code is in the main
folder and the unit tests are located in the test
folder. Although you can change the default layout, Maven tends to work best with the default layout.
In addition to the code, you can see a file named pom.xml
that is located in the root directory in the previous image. This is a project object model file that describes the project, its properties, and its dependencies. That's right—you don't need to manually download dependencies if they are present in one of the available Maven repositories—during its work, Maven will download them, put them in your local repository on your hard disk, and use it when needed. All you need to care about is writing an appropriate pom.xml
section that will inform Maven which dependencies should be used.
For example, this is an example Maven pom.xml
file:
<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>pl.solr</groupId> <artifactId>analyzer</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>analyzer</name> <url>http://solr.pl</url> <properties> <elasticsearch.version>1.4.1</elasticsearch.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>${elasticsearch.version}</version> </dependency> </dependencies> </project>
This is a simplified version of a pom.xml
file that we will extend in the rest of the chapter. You can see that it starts with the root project
tag and then defines the group identifier, the artifact identifier, the version, and the packaging method (in our case, the standard build command will create a jar file). In addition to this, we've specified a single dependency—the Elasticsearch library Version 1.4.1.
In order to run the build process, what we need to do is simply run the following command in the directory where the pom.xml
file is present:
mvn clean package
It will result in running Maven. It will clean all the generated content in the working directory, compile and package our code. Of course, if we have unit tests, they will have to pass in order for the package to be built. The built package will be written into the target
directory created by Maven.
If you want to learn more about the Maven life cycle, please refer to http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html.
In order to build the ZIP file that will contain our plugin code, we need to package it. By default, Maven doesn't support pure ZIP files' packaging, so in order to make it all work, we will use the Maven Assembly plugin (you can find more about the plugin at http://maven.apache.org/plugins/maven-assembly-plugin/). In general, the described plugin allows us to aggregate the project output along with its dependencies, documentations, and configuration files into a single archive.
In order for the plugin to work, we need to add the build
section to our pom.xml
file that will contain information about the assembly plugin, the jar plugin (which is responsible for creating the proper jar), and the compiler plugin, because we want to be sure that the code will be readable by Java 7. In addition to this, let's assume that we want our archive to be put into the target/release
directory of our project. The relevant section of the pom.xml
file should look as follows:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.3</version> <configuration> <finalName>elasticsearch-${project.name}-${elasticsearch.version}</finalName> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.2.1</version> <configuration> <finalName>elasticsearch-${project.name}-${elasticsearch.version}</finalName> <appendAssemblyId>false</appendAssemblyId> <outputDirectory>${project.build.directory}/release/</outputDirectory> <descriptors> <descriptor>assembly/release.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>generate-release-plugin</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build>
If you look closely at the assembly plugin configuration, you'll notice that we specify the assembly descriptor called release.xml
in the assembly
directory. This file is responsible for specifying what kind of archive we want to have as the output. Let's put the following release.xml
file in the assembly
directory of our project:
<?xml version="1.0"?> <assembly> <id>bin</id> <formats> <format>zip</format> </formats> <includeBaseDirectory>false</includeBaseDirectory> <dependencySets> <dependencySet> <unpack>false</unpack> <outputDirectory>/</outputDirectory> <useProjectArtifact>false</useProjectArtifact> <useTransitiveFiltering>true</useTransitiveFiltering> <excludes> <exclude>org.elasticsearch:elasticsearch</exclude> </excludes> </dependencySet> </dependencySets> <fileSets> <fileSet> <directory>${project.build.directory}/</directory> <outputDirectory>/</outputDirectory> <includes> <include>elasticsearch-${project.name}-${elasticsearch.version}.jar</include> </includes> </fileSet> </fileSets> </assembly>
Again, we don't need to know all the details; however, it is nice to understand what is going on, even on the general level. The preceding code file tells the Maven Assembly plugin that we want our archive to be packed with ZIP (<format>zip</format>
), and we want Elasticsearch libraries to be excluded (the exclude
section), because they will already be present in Elasticsearch, where we will install the plugin. In addition to this, we've specified that we want our project jar to be included (the includes
section).
If you want to see the full project structure with the full pom.xml
file and all the needed files, please look at the code provided with the book for Chapter 9,
Developing Elasticsearch Plugins.