Apache Maven is a dependency management and a build automation tool, primarily used for Java applications. Maven continues to use XML files just like Ant but in a much more manageable way. The name of the game here is convention over configuration.
While Ant gives the flexibility and requires everything to be written from scratch, Maven relies on conventions and provides predefined commands (goals).
Maven was released in 2004. Its goal was to improve upon some of the problems developers were facing when using Ant.
Maven continues using XML as the format to write build specification. However, structure is diametrically different. While Ant requires developers to write all the commands that lead to the successful execution of some task, Maven relies on conventions and provides the available targets (goals) that can be invoked. As the additional, and probably most important addition, Maven introduced the ability to download dependencies over the network (later on adopted by Ant through Ivy). That in itself revolutionized the way we deliver software.
However, Maven has its own problems. Dependencies management does not handle conflicts well between different versions of the same library (something Ivy is much better at). XML as the build configuration format is strictly structured and highly standardized. Customization of targets (goals) is hard. Since Maven is focused mostly on dependency management, complex, customized build scripts are actually harder to write in Maven than in Ant.
Maven configuration written in XML continuous being big and cumbersome. On bigger projects it can have hundreds of lines of code without actually doing anything “extraordinary”.
Main benefit from Maven is its life-cycle. As long as the project is based on certain standards, with Maven one can pass through the whole life cycle with relative ease. This comes at a cost of flexibility.
Simply put, Maven allows us to focus on what our build should do, and gives us the framework to do it. Another positive aspect of Maven was that it provided built-in support for dependency management.
Maven’s configuration file, containing build and dependency management instructions, is by convention called pom.xml. Additionally, Maven also prescribes strict project structure, while Ant provides flexibility there as well.
Here’s an example of a pom.xml file for the same simple Java project with the HelloWorld main class from before:
<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>baeldung</groupId> <artifactId>mavenExample</artifactId> <version>0.0.1-SNAPSHOT</version> <description>Maven example</description> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </project>
However, now the project structure has been standardized as well and conforms to the Maven conventions:
+---src | +---main | | +---java | | | \---com | | | \---baeldung | | | \---maven | | | HelloWorld.java | | | | | \---resources | \---test | +---java | \---resources
As opposed to Ant, there is no need to define each of the phases in the build process manually. Instead, we can simply call Maven’s built-in commands.
For example, we can compile the code by running:
mvn compile </soure> At its core, as noted on official pages, Maven can be considered a plugin execution framework, since all work is done by plugins. Maven supports a wide range of available plugins, and each of them can be additionally configured. One of the available plugins is Apache Maven Dependency Plugin which has a copy-dependencies goal that will copy our dependencies to a specified directory. To show this plugin in action, let’s include this plugin in our pom.xml file and configure an output directory for our dependencies: <source> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>target/dependencies </outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>
This plugin will be executed in a package phase, so if we run:
We’ll execute this plugin and copy dependencies to the target/dependencies folder.
There is also an existing article on how to create an executable JAR using different Maven plugins. Additionally, for a detailed Maven overview, have a look at this core guide on Maven, where some Maven’s key features are explored.
Maven became very popular since build files were now standardized and it took significantly less time to maintain build files, comparing to Ant. However, though more standardized than Ant files, Maven configuration files still tend to get big and cumbersome.
Maven’s strict conventions come with a price of being a lot less flexible than Ant. Goal customization is very hard, so writing custom build scripts is a lot harder to do, compared with Ant.
Although Maven has made some serious improvements regarding making application’s build processes easier and more standardized, it still comes with a price due to being a lot less flexible than Ant. This lead to the creation of Gradle which combines best of both worlds – Ant’s flexibility and Maven’s features.
In the mean time the interest for DSLs (Domain Specific Languages) continued increasing. The idea is to have languages designed to solve problems belonging to a specific domain. In case of builds, one of the results of applying DSL is Gradle.
Maven Repository Link : https://mvnrepository.com/
Sample Spring maven comfiguration:
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.6.RELEASE</version> </dependency>