Apache Maven

Last updated
Apache Maven
Developer(s) The Apache Software Foundation
Initial release13 July 2004;19 years ago (2004-07-13)
Stable release
3.9.6 / 1 December 2023;39 days ago (2023-12-01) [1]
Repository
Written in Java
Type Build tool
License Apache License 2.0
Website maven.apache.org

Maven is a build automation tool used primarily for Java projects. Maven can also be used to build and manage projects written in C#, Ruby, Scala, and other languages. The Maven project is hosted by The Apache Software Foundation, where it was formerly part of the Jakarta Project.

Contents

Maven addresses two aspects of building software: how software is built and its dependencies. Unlike earlier tools like Apache Ant, it uses conventions for the build procedure. Only exceptions need to be specified. An XML file describes the software project being built, its dependencies on other external modules and components, the build order, directories, and required plug-ins. It comes with pre-defined targets for performing certain well-defined tasks such as compilation of code and its packaging. Maven dynamically downloads Java libraries and Maven plug-ins from one or more repositories such as the Maven 2 Central Repository, and stores them in a local cache. [2] This local cache of downloaded artifacts can also be updated with artifacts created by local projects. Public repositories can also be updated.

Maven is built using a plugin-based architecture that allows it to make use of any application controllable through standard input. A C/C++ native plugin is maintained for Maven 2. [3]

Alternative technologies like Gradle and sbt as build tools do not rely on XML, but keep the key concepts Maven introduced. With Apache Ivy, a dedicated dependency manager was developed as well that also supports Maven repositories. [4]

Apache Maven has support for reproducible builds. [5] [6]

History

The number of artifacts on Maven's central repository has grown rapidly Maven repository artifact growth.png
The number of artifacts on Maven's central repository has grown rapidly

Maven was created by Jason van Zyl in 2002 and began as a sub-project of Apache Turbine. In 2003 Maven was accepted as a top level Apache Software Foundation project.

Version history:

Syntax

Maven projects are configured using a Project Object Model (POM) in a pom.xml file.

Example file:

<project><!-- model version is always 4.0.0 for Maven 2.x POMs --><modelVersion>4.0.0</modelVersion><!-- project coordinates, i.e. a group of values which uniquely identify this project --><groupId>com.mycompany.app</groupId><artifactId>my-app</artifactId><version>1.0</version><!-- library dependencies --><dependencies><!-- The coordinates of a required library.           The scope is 'test' to indicate the library           is only used for running tests. --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>5.9.1</version><scope>test</scope></dependency></dependencies></project>

This POM defines a unique identifier for the project (coordinates) and a single dependency on the JUnit library. However, that is already enough for building the project and running the unit tests associated with the project. Maven accomplishes this by embracing the idea of Convention over Configuration, that is, Maven provides default values for the project's configuration.

The directory structure of a normal idiomatic Maven project has the following directory entries:

A directory structure for a Java project auto-generated by Maven Maven CoC.svg
A directory structure for a Java project auto-generated by Maven
Directory namePurpose
project homeContains the pom.xml and all subdirectories.
src/main/javaContains the deliverable Java source code for the project.
src/main/resourcesContains the deliverable resources for the project, such as property files.
src/test/javaContains the testing Java sourcecode (JUnit or TestNG test cases, for example) for the project.
src/test/resourcesContains resources necessary for testing.

The command mvn package will compile all the Java files, run any tests, and package the deliverable code and resources into target/my-app-1.0.jar (assuming the artifactId is my-app and the version is 1.0.)

Using Maven, the user provides only configuration for the project, while the configurable plug-ins do the actual work of compiling the project, cleaning target directories, running unit tests, generating API documentation and so on. In general, users should not have to write plugins themselves. Contrast this with Ant and make, in which one writes imperative procedures for doing the aforementioned tasks.

Design

Project Object Model

A Project Object Model (POM) [7] provides all the configuration for a single project. General configuration covers the project's name, its owner and its dependencies on other projects. One can also configure individual phases of the build process, which are implemented as plugins. For example, one can configure the compiler-plugin to use Java version 1.5 for compilation, or specify packaging the project even if some unit tests fail.

Larger projects should be divided into several modules, or sub-projects, each with its own POM. One can then write a root POM through which one can compile all the modules with a single command. POMs can also inherit configuration from other POMs. All POMs inherit from the Super POM [8] by default. The Super POM provides default configuration, such as default source directories, default plugins, and so on.

Plug-ins

Most of Maven's functionality is in plug-ins. A plugin provides a set of goals that can be executed using the command mvn [plugin-name]:[goal-name]. For example, a Java project can be compiled with the compiler-plugin's compile-goal [9] by running mvn compiler:compile.

There are Maven plugins for building, testing, source control management, running a web server, generating Eclipse project files, and much more. [10] Plugins are introduced and configured in a <plugins>-section of a pom.xml file. Some basic plugins are included in every project by default, and they have sensible default settings.

However, it would be cumbersome if the archetypal build sequence of building, testing and packaging a software project required running each respective goal manually:

Maven's lifecycle concept handles this issue.

Plugins are the primary way to extend Maven. Developing a Maven plugin can be done by extending the org.apache.maven.plugin.AbstractMojo class. Example code and explanation for a Maven plugin to create a cloud-based virtual machine running an application server is given in the article Automate development and management of cloud virtual machines. [11]

Build lifecycles

The build lifecycle is a list of named phases that can be used to give order to goal execution. One of Maven's three standard lifecycles is the default lifecycle, which includes the following phases, performed in the order listed: [12]

Goals provided by plugins can be associated with different phases of the lifecycle. For example, by default, the goal compiler:compile is associated with the compile phase, while the goal surefire:test is associated with the test phase. When the mvn test command is executed, Maven runs all goals associated with each of the phases up to and including the test phase. In such a case, Maven runs the resources:resources goal associated with the process-resources phase, then compiler:compile, and so on until it finally runs the surefire:test goal.

Maven also has standard phases for cleaning the project and for generating a project site. If cleaning were part of the default lifecycle, the project would be cleaned every time it was built. This is clearly undesirable, so cleaning has been given its own lifecycle.

Standard lifecycles enable users new to a project the ability to accurately build, test and install every Maven project by issuing the single command mvn install. By default, Maven packages the POM file in generated JAR and WAR files. Tools like diet4j [13] can use this information to recursively resolve and run Maven modules at run-time without requiring an "uber"-jar that contains all project code.

Dependencies

A central feature in Maven is dependency management. Maven's dependency-handling mechanism is organized around a coordinate system identifying individual artifacts such as software libraries or modules. The POM example above references the JUnit coordinates as a direct dependency of the project. A project that needs, say, the Hibernate library simply has to declare Hibernate's project coordinates in its POM. Maven will automatically download the dependency and the dependencies that Hibernate itself needs (called transitive dependencies) and store them in the user's local repository. Maven 2 Central Repository [2] is used by default to search for libraries, but one can configure the repositories to be used (e.g., company-private repositories) within the POM.

The fundamental difference between Maven and Ant is that Maven's design regards all projects as having a certain structure and a set of supported task work-flows (e.g., getting resources from source control, compiling the project, unit testing, etc.). While most software projects in effect support these operations and actually do have a well-defined structure, Maven requires that this structure and the operation implementation details be defined in the POM file. Thus, Maven relies on a convention on how to define projects and on the list of work-flows that are generally supported in all projects. [14]

There are search engines such as The Central Repository Search Engine, [15] which can be used to find out coordinates for different open-source libraries and frameworks.

Projects developed on a single machine can depend on each other through the local repository. The local repository is a simple folder structure that acts both as a cache for downloaded dependencies and as a centralized storage place for locally built artifacts. The Maven command mvn install builds a project and places its binaries in the local repository. Then, other projects can utilize this project by specifying its coordinates in their POMs.

Interoperability

Add-ons to several popular integrated development environments (IDE) targeting the Java programming language exist to provide integration of Maven with the IDE's build mechanism and source editing tools, allowing Maven to compile projects from within the IDE, and also to set the classpath for code completion, highlighting compiler errors, etc.

Examples of popular IDEs supporting development with Maven include:

These add-ons also provide the ability to edit the POM or use the POM to determine a project's complete set of dependencies directly within the IDE.

Some built-in features of IDEs are forfeited when the IDE no longer performs compilation. For example, Eclipse's JDT has the ability to recompile a single Java source file after it has been edited. Many IDEs work with a flat set of projects instead of the hierarchy of folders preferred by Maven. This complicates the use of SCM systems in IDEs when using Maven. [16] [17] [18]

See also

Related Research Articles

The Comprehensive Perl Archive Network (CPAN) is a repository of over 250,000 software modules and accompanying documentation for 39,000 distributions, written in the Perl programming language by over 12,000 contributors. CPAN can denote either the archive network or the Perl program that acts as an interface to the network and as an automated software installer. Most software on CPAN is free and open source software.

JUnit is a unit testing framework for the Java programming language. JUnit has been important in the development of test-driven development, and is one of a family of unit testing frameworks which is collectively known as xUnit that originated with SUnit.

<span class="mw-page-title-main">Apache Ant</span> Java software tool

Apache Ant is a software tool for automating software build processes which originated from the Apache Tomcat project in early 2000 as a replacement for the Make build tool of Unix. It is similar to Make, but is implemented using the Java language and requires the Java platform. Unlike Make, which uses the Makefile format, Ant uses XML to describe the code build process and its dependencies.

TestNG is a testing framework for the Java programming language created by Cédric Beust and inspired by JUnit and NUnit. The design goal of TestNG is to cover a wider range of test categories: unit, functional, end-to-end, integration, etc., with more powerful and easy-to-use functionalities.

Apache Gump is an open source continuous integration system, which aims to build and test all the open source Java projects, every night. Its aim is to make sure that all the projects are compatible, at both the API level and in terms of functionality matching specifications. It is hosted at gump.apache.org, and runs every night on the official Sun JVM.

A software repository, or repo for short, is a storage location for software packages. Often a table of contents is also stored, along with metadata. A software repository is typically managed by source or version control, or repository managers. Package managers allow automatically installing and updating repositories, sometimes called "packages".

<span class="mw-page-title-main">Hudson (software)</span> Continuous integration tool

Hudson is a discontinued continuous integration (CI) tool written in Java, which runs in a servlet container such as Apache Tomcat or the GlassFish application server. It supports SCM tools including CVS, Subversion, Git, Perforce, Clearcase and RTC, and can execute Apache Ant and Apache Maven based projects, as well as arbitrary shell scripts and Windows batch commands. The primary developer of Hudson was Kohsuke Kawaguchi, who worked for Sun Microsystems at the time. Released under the MIT License, Hudson is free software.

<span class="mw-page-title-main">Apache Ivy</span>

Apache Ivy is a transitive package manager. It is a sub-project of the Apache Ant project, with which Ivy works to resolve project dependencies. An external XML file defines project dependencies and lists the resources necessary to build a project. Ivy then resolves and downloads resources from an artifact repository: either a private repository or one publicly available on the Internet.

<span class="mw-page-title-main">Spring Roo</span> Open-source software tool

Spring Roo is an open-source software tool that uses convention-over-configuration principles to provide rapid application development of Java-based enterprise software. The resulting applications use common Java technologies such as Spring Framework, Java Persistence API, Thymeleaf, Apache Maven and AspectJ. Spring Roo is a member of the Spring portfolio of projects.

sbt (software) Open-source build tool for Scala and Java projects

sbt is an open-source build tool created explicitly for Scala and Java projects. It aims to streamline the procedure of constructing, compiling, testing, and packaging applications, libraries, and frameworks. sbt is highly adaptable, permitting developers to customize the build process according to their project's specific needs.

<span class="mw-page-title-main">Google Plugin for Eclipse</span> Set of Java development tools

Google Plugin for Eclipse (GPE) was a set of development tools that enabled Java developers to design, build, optimize, and deploy cloud computing applications. developers in creating complex user interfaces, generating Ajax code using the GWT Web Toolkit, and deploying applications to Google App Engine. GPE installed into the Eclipse integrated development environment (IDE) using the extensible plugin system. GPE was available under the Eclipse Public License 1.0.

<span class="mw-page-title-main">Jenkins (software)</span> Open source automation server

Jenkins is an open source automation server. It helps automate the parts of software development related to building, testing, and deploying, facilitating continuous integration, and continuous delivery. It is a server-based system that runs in servlet containers such as Apache Tomcat. It supports version control tools, including AccuRev, CVS, Subversion, Git, Mercurial, Perforce, ClearCase, and RTC, and can execute Apache Ant, Apache Maven, and sbt based projects as well as arbitrary shell scripts and Windows batch commands.

<span class="mw-page-title-main">Gradle</span> Free software build automation tool

Gradle is a build automation tool for multi-language software development. It controls the development process in the tasks of compilation and packaging to testing, deployment, and publishing. Supported languages include Java, C/C++, and JavaScript. Gradle builds on the concepts of Apache Ant and Apache Maven, and introduces a Groovy- and Kotlin-based domain-specific language contrasted with the XML-based project configuration used by Maven. Gradle uses a directed acyclic graph to determine the order in which tasks can be run, through providing dependency management. It runs on the Java Virtual Machine.

Java code coverage tools are of two types: first, tools that add statements to the Java source code and require its recompilation. Second, tools that instrument the bytecode, either before or during execution. The goal is to find out which parts of the code are tested by registering the lines of code executed when running a test.

MockServer is an open source mocking framework for HTTP and HTTPS released under the Apache License. MockServer is designed to simplify integration testing, by mocking HTTP and HTTPS system such as a web service or web site, and to decouple development teams, by allowing a team to develop against a service that is not complete or is unstable.

<span class="mw-page-title-main">Bazel (software)</span> Software tool that automates software builds and tests

Bazel is a free and open-source software tool used for the automation of building and testing software. Google uses the build tool Blaze internally and released an open-sourced port of the Blaze tool as Bazel, named as an anagram of Blaze. Bazel was first released in March 2015 and was in beta status by September 2015. Version 1.0 was released in October 2019.

Grunt is a JavaScript task runner, a tool used to automatically perform frequent tasks such as minification, compilation, unit testing, and linting. It uses a command-line interface to run custom tasks defined in a file. Grunt was created by Ben Alman and is written in Node.js. It is distributed via npm. As of October 2022, there were more than 6,000 plugins available in the Grunt ecosystem.

<span class="mw-page-title-main">Spring Boot</span> Application framework for Java platform

Spring Boot Extension is Spring's convention-over-configuration solution intended to aid in creating production-grade Spring applications with minimal amounts of configuration. Most of the application can be preconfigured using Spring team's "opinionated view" of the best configuration and use of the Spring platform and third-party libraries. A Spring Boot application can be written using several programming languages, including Java and Kotlin.

In version-control systems, a monorepo is a software-development strategy in which the code for a number of projects is stored in the same repository. This practice dates back to at least the early 2000s, when it was commonly called a shared codebase. Google, Meta, Microsoft, Uber, Airbnb, and Twitter all employ very large monorepos with varying strategies to scale build systems and version control software with a large volume of code and daily changes.

References

  1. "Maven Release Notes – Maven 3.9.6". maven.apache.org.
  2. 1 2 "Index of /maven2/". Archived from the original on 2018-09-17. Retrieved 2009-04-15.
  3. Laugstol, Trygve. "MojoHaus Native Maven Plugin".
  4. "IBiblio Resolver | Apache Ivy™".
  5. "Reproducible/Verifiable Builds - Apache Maven - Apache Software Foundation". cwiki.apache.org.
  6. "Reproducible Builds in Java - DZone Java". dzone.com.
  7. POM Reference
  8. Super POM
  9. Punzalan, Edwin. "Apache Maven Compiler Plugin – Introduction".
  10. Marbaise, Brett Porter Jason van Zyl Dennis Lundberg Olivier Lamy Benson Margulies Karl-Heinz. "Maven – Available Plugins".
  11. Amies, Alex; Zou P X; Wang Yi S (29 Oct 2011). "Automate development and management of cloud virtual machines". IBM DeveloperWorks. IBM.
  12. Porter, Brett. "Maven – Introduction to the Build Lifecycle".
  13. "diet4j - put Java JARs on a diet, and load maven modules as needed".
  14. "Maven: The Complete Reference". Sonatype. Archived from the original on 21 April 2013. Retrieved 11 April 2013.
  15. The Central Repository Search Engine
  16. "maven.apache.org/eclipse-plugin.html". Archived from the original on May 7, 2015.
  17. "IntelliJ IDEA :: Features". Archived from the original on 2015-05-24. Retrieved 2009-09-02.
  18. "MavenBestPractices - NetBeans Wiki".

Further reading