If you are a Java developer, one of the most frequent words that you hear during your career is Maven. So, what is Maven, and what does it do? This article gives you a basic idea about what Maven is and the important concepts associated with it. What Is Apache Maven? Although Maven is considered a that can be used to build artifacts from the source code by many, it is actually a that offers the build tool capabilities as a subset of its capabilities. build tool project management tool As indicated on the official site, , https://maven.apache.org Apache Maven is a Software project management and comprehension tool. Based on the concept of a project object model(POM), Maven can manage a project’s build, reporting, and documentation from a central piece of information. Looking at Maven comprehensively, This is a with a project object model. project management tool Which has a . set of standards Which has a . project lifecycle A . dependency management system A logic that during various lifecycle phases. executes plugin goals Having the aforementioned features, Maven can give a simple project setup that uses the best practices, and with Maven, the projects can follow a that is independent of the IDEs(Integrated Development Environments). consistent structure In addition, one of the most important usages of Maven is that it simplifies the declaration of project dependencies. Focusing on the last point, when you build a traditional Java application, you include the dependencies by downloading them directly and including them in the project structure. If you have already done this you know how much of a laborious work that is. In addition, to download those dependencies, you have to keep track of their versions for your project to work. But that is where Maven comes to help. It helps you to along with downloading them when they are needed to build the project. keep track of your dependencies and their respective versions Installing Apache Maven Installing Apache Maven Directly To install Maven, you need to have JDK (Java Development Kit) installed on your machine first. You can simply download the JDK binary file, and extract it or use an installer. After that, you can go to , and click the link. You can either click the in the side panel or the in the content section. http://maven.apache.org Download Download Download, Install, Run Maven When you click that link, you will be redirected to the downloads page, where you will see the system requirements for Maven (Always try to download the latest version of Maven). The most important requirement here is the JDK version. Right now, the latest version is Maven 3.9.5 and the JDK version required for that is JDK 1.8. And when you scroll down, you will see the and the downloadable files. Here, we can select the to download. After downloading the binary zip file, extract it, and set the and paths in the environment settings. installation instructions apache-maven-3.9.5-bin.tar.gz JAVA_HOME MAVEN_HOME The following steps show how to install Maven to a MacOS that already has JDK >= 1.8 installed. Go to the directory in MacOS using the terminal. → Downloads cd ~/Downloads Extract the zip file. → apache-maven-3.9.5-bin.tar.gz tar -xvf apache-maven-3.9.5.bin.tar.gz Copy the extracted directory to directory. → apache-maven-3.9.5 /opt/ sudo mv ~/Downloads/apache-maven-3.9.5 /opt/ Open the or in your Mac (Depending on the terminal you use) → ~/.zshrc ~/.bash_profile open ~/.zshrc Add the following two lines to the file. → MAVEN_HOME="/opt/apache-maven-3.9.5" export PATH="$MAVEN_HOME/bin:$PATH" Finally, source the or file. → ~/.zshrc ~/.bash_profile source ~/.zshrc After installing the Apache Maven, you can check whether it is working by using either of the following two commands. mvn -v mvn -version The instructions on how to install Maven on Windows and Linux machines are explained in the following articles. https://medium.com/javarevisited/understanding-maven-7df0ae4ada7b https://www.digitalocean.com/community/tutorials/install-maven-linux-ubuntu Installing JDK and Maven With SDKMAN SDKMAN is a tool which allows you to download and manage SDKs. Using this, you are able to switch between multiple versions of the same SDK. To install SDKMAN, go to . https://sdkman.io/ Here, I will explain how to install it on a MacOS machine, and you can find the details on how to install it on Windows or Linux at their official site. Open the terminal, and run the following → curl -s “https://get.sdkman.io” | bash Follow the on-screen instructions to wrap up the installation. Type source “$HOME/.sdkman/bin/sdkman-init.sh After that, open your or to verify the following is included at the end of the file. ~/.zshrc ~/.bash_profile export SDKMAN_DIR="$HOME/.sdkman" [[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]] && source "$HOME/.sdkman/bin/sdkman-init.sh" After that, type the following to verify whether it is working. → sdk version Install JDK With SDKMAN To install JDK with SDKMAN, follow the below instructions. Type to list down all the Java versions that can be used with SDKMAN. sdk list java Then copy the identifier of the Java version you want (e.g., from Corretto). 8.0.372-amzn Then type and run to install that version. sdk install 8.0.372-amzn By default, the first Java version you will install will be your default Java version. If you want another Java version installed, (e.g. ) then type and run 11.0.20-amzn sdk install 11.0.20-amzn To change the Java version from to , type . 8.0.372-amzn 11.0.20-amzn sdk use java 11.0.20-amzn If you want to remove a Java version (e.g., ), you can simply type and run 8.0.372-amzn sdk uninstall java 8.0.372-amzn Install Maven With SDKMAN Install Maven with SDKMAN is similar to how you installed the JDK with SDKMAN. Type to list down all the Maven versions that are available. sdk list maven Select the preferred Maven version, and type to install it. sdk install <mvn-version> Similar to JDK uninstallation, you can remove an unwanted Maven version by typing and running . sdk uninstall <mvn-version> After installing both Java and Maven, you can check whether they are working by typing the below commands. java -version mvn -v Configurations and Repository Once you start using Maven, you will notice that Maven has created local, user-specific configuration files and a local repository in the directory. Inside that there are, ~/.m2 ~/.m2 → A file containing the user-specific configurations for authentication, repositories, and other information to customize the behavior of Maven. ~/.m2/settings.xml → This directory contains the local Maven repository. When you download a dependency from a remote Maven repository, Maven stores a copy of that dependency in your local repository. ~/.m2/repository Remote Maven repositories have the dependencies uploaded by certain organizations, and the local repository is the in our local machine. ~/.m2/repository For instance, if we need, in our project, we can mention that to Maven, and it will download it from a remote repository like Maven Central( ) or MVN Repository( ) and put it inside the directory. org.apache.spark.spark-sql https://central.sonatype.com/ https://mvnrepository.com/ ~/.m2/repository The Project Object Model The project Object Model or the POM is an essential file in Maven Development since it declares the project’s identity and structure. This is usually described in XML. The POM file contains four categories of description and configuration. General Project Information → This includes a project’s name, the URL for a project, the sponsoring organization, and a list of developers and contributors along with the license for a project. Build Settings → This section can be used to customize the default Maven build. It is possible to change the location of resources and tests, add new plugins, and add new plugin goals to the lifecycle using this section. Build Environment → The build environment has profiles that can be activated for use in different environments. POM Relationships → Usually, a project depends on other projects and inherits POM settings from its parent project. These relationships are defined in this section. The Super POM All the Maven project POM files extend the , which defines a set of defaults shared by all projects. This file comes as a part of the installation and can be found in, Super POM file in for Maven 2. maven-<version>-uber.jar ${M2_HOME}/lib file in for Maven 3. maven-model-builder-<version>.jar ${M2_HOME}/lib And, if you have installed Maven via SDKMAN you can find it on ~/.sdkman/candidates/maven/<maven-version>/lib Since all the Maven POMs inherit the defaults from the , if you want, you can, Super POM Write a simple project that produces a JAR from a source in src/main/java Want to run JUnit tests src/test/java Want to build a project site using mvn site To do those things, you don’t have to customize anything. You can use a simple POM file like the one shown below. <project> <modelVersion>4.0.0</modelVersion> <groupId>org.mavensample.project</groupId> <artifactId>simplest</artifactId> <version>1</version> </project> Since this is the simplest POM file you can have, it is normally known as the If you want to create a simple program that belongs to the above criteria, you can type and run , and it will produce a JAR file in Simplest POM. mvn package /target/simples-1.jar The Effective POM The brings us over to the concept called The is made of a combination of super POM and parent POM files. It is notable that Simplest POM Effective POM. Effective POM the default configurations can be overridden by the parent POM files and the current project’s POM when creating an effective POM. To find a project’s , you’ll need to run the goal in plugin using, Effective POM effective-pom Maven Help mvn help:effective-pom This will print out an showing the merges between the aforementioned POM files. To use the , you need to have the plugin goal defined. To install the plugin, you can use the below code, and include that in your POM file. XML document mvn help:effective-pom Maven Help help Maven Help <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-help-plugin</artifactId> <version>3.4.0</version> <!-- Use the latest version --> </plugin> </plugins> </build> POM Syntax A Maven project’s version encodes a release version number that is used to group and order releases. A Maven version has the following parts. Major version Minor version Incremental version Qualifier These parts correspond to the following format. <major version>.<minor version>.<incremental version>-qualifier For example, the version has a major version of 1, a minor version of 2, and an incremental version of 3. The version has a major version of 1 and no minor or incremental versions. The qualifier is used to capture the milestone builds like alpha and beta releases ( ) 1.2.3 `1` 1.2.3-beta-01 When using version build numbers like and you should always use left padding (01,02, etc.) to ensure Maven build number issues. 1.1.2-beta-01 1.1.2-beta-10 Maven versions also can contain a string literal to signify that a project is currently under active development by adding the string . This string token will be expanded to a UTC(Coordinated Universal Time Value, e.g., 20230207-230803-1). (e.g., → ) SNAPSHOT 1.0-SNAPSHOT 1.0-20230207-230803-1 As a default setting, Maven will not check the versions on remote repositories. To depend on releases, you have to explicitly enable the ability to download them using a or element in POM. SNAPSHOT SNAPSHOT repository pluginRepository Also, POM can include references to properties preceded by a dollar sign( ) and surrounded by two curly braces. $ <project> <modelVersion>4.0.0</modelVersion> <groupId>org.mavensample.project</groupId> <artifactId>project-x</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <build> <finalName>${project.groupId}-${project.artifactId}</finalName> </build> </project> If you put the above in your file and run , you will see the output contains the line, pom.xml mvn help:effective-pom <finalName>org.mavensample.project-project-x</finalName> Maven provides three implicit variables that can be used to access environment variables, POM information, and Maven Settings. →This exposes the environment variables defined by your operating system or shell. For example, reference to would be replaced by the environment variable. env ${env.JAVA_HOME} ${JAVA_HOME} →This exposes the POM. You can use the dot-notation path references here. project →This exposes the Maven settings information. You can use dot notation to refer to the values defined in the file. For example, would reference the value of the element in . settings settings.xml ${settings.offline} offline ~/.m2/settings.xml In addition to the above three, you can reference the system properties and the arbitrary properties set in the Maven POM or build profile. Java System Properties → All the properties are accessible via defined on .(e.g., , ) getProperties() java.lang.System ${user.name} ${java.home} Arbitrary properties → These can be set with the element in the POM file or the or can be loaded from external files. <properties></properties> settings.xml <properties> <org.mavensample.project.version>1.0</org.mavensample.project.version> </properties> Project Dependencies Maven can manage both internal and external dependencies. An external dependency for a Java project might be a library like or . An internal dependency for a Java project can be a web application depending on another project that contains the service class, model objects, or persistence logic. Spring Framework Log4j When you define a dependency, you are using , , , and to define a unique location of that dependency. This is also done when you are creating a new Maven project. These are called and they are integral when defining the dependencies. groupId artifactId version classifier Maven Coordinates Dependency Scope There are five dependency scopes. These show what phases we are using the dependency. → is the default scope; all the dependencies are scoped if a scope is not defined. dependencies are available in all classpaths, and they are packaged. compile compile compile compile → dependencies are used when you expect JDK or a container to provide them. For example, if you are developing a web application, you need the Servlet API available on the compile classpath to compile a servlet, but you don’t need to include the Servlet API in the packaged WAR file. In this case, scope should be used. These dependencies . They are not transitive, nor they are packaged. provided provided provided are available on the compilation(not runtime) classpath → dependencies are required to execute and test the system, but they are not required for compilation. For example, you may need a JDBC API JAR at compile time and JDBC driver implementation only at runtime. runtime runtime → These dependencies are not required during the normal operation of an application and they are only needed during the test compilation and execution phases. test → This scope is similar to , but must specify the explicit path to the JAR on the local file system. If you declare the scope , you must also provide the element. This is not a recommended scope to be used. system provided system systemPath Optional Dependencies When you need a dependency to compile a specific project but you don’t need it to be shown up as a transitive runtime dependency for the project that uses your specific project, you can use optional dependencies. You can use the for that. <optional>true</optional> Usually, you don’t need to use optional dependencies. Instead of one large project with a series of optional dependencies, you should always separate the project into submodules and use the specific dependency in the specific project. Dependency Version Ranges In Maven, you don’t need to depend on a specific version of a dependency; you can specify a range of versions that would satisfy a given dependency. → exclusive quantifiers (e.g., ). (,) <version>(1.0,3.0)</version> → inclusive quantifiers (e.g., ). [,] <version>[1.0,3.0]</version> Mixed → (e.g., ). <version>(1.0,3.0]</version> Transitive Dependencies A transitive dependency is a dependency of a dependency. If depends on , which depends on , then is a transitive dependency of . If depends on , then it is also considered a transitive dependency of . project-a project-b project-c project-c project-a project-a project-d project-a The best way to look at the transitive dependencies of a project is to type and run the following command. mvn dependency:tree Conflict Resolution Sometimes, you need to exclude a transitive dependency, such as when you depend on a project that depends on another project, but you would like to either exclude the dependency altogether or replace the transitive dependency with another dependency that provides the same functionality. An example is shown below. <dependency> <groupId>org.mavensample.project</groupId> <artifactId>project-x</artifactId> <version>1.0</version> <exclusions> <exclusion> <groupId>org.mavensample.project</groupId> <artifactId>project-y</artifactId> </exclusion> </exclusions> </dependency> Dependency Management If you have a large set of projects that use the same set of dependencies, you can define a dependency management block in your muti-module project’s top-level POM. An example is shown below of how you can use the MySQL Java connector version 5.1.2 in the top-level POM. <dependencyManagement> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.2</version> </dependency> ... <dependencies> </dependencyManagement> Then you can use them in a child project, without using the version metadata or without declaring it since it is getting inherited. The Build Lifecycle A build lifecycle is an organized sequence of phases that can be used to give orders or goals. Those goals can be used in the project to do multiple tasks. There are three standard lifecycles in Maven. → Running invokes this and the plugin’s clean goal ( ) is bound to this. clean mvn clean Clean clean:clean →This is the general model of a build process for a software application. It contains several important phases like , , , , default/build generate-resources test compile install deploy → This can be used to generate a site from the Maven project by running . site mvn site Build Profiles Profiles allow the user to customize a particular build for a particular environment. In other words, profiles enable portability between different environments. An example is shown below. <profile> <id>jdk16</id> <activation> <activeByDefault>false</activeByDefault> <jdk>1.6</jdk> <property> <name>!environment.type</name> </property> </activation> <modules> <module>simple-script</module> </modules> </profile> As you can notice sets the default profile to be activated, and makes sure that the profile is activated when the value is not present. activeByDefault <property></property> environment.type To list all the active profiles, you can use the following command. mvn help:active-profiles Usually, a POM can have several profiles to activate different environments like the example given below. <profiles> <profile> <id>development</id> <activation> <activeByDefault>true</activeByDefault> <property> <name>environment.type</name> <value>dev</value> </property> </activation> <properties> <database.driverClassName>com.mysql.jdbc.Driver</database.driverClassName> <database.url>jdbc:mysql://localhost:3306/app_dev</database.url> <database.user>dev_user</database.user> <database.password>deve_password</database.password> </properties> </profile> <profile> <id>production</id> <activation> <property> <name>environment.type</name> <value>prod</value> </property> </activation> <properties> <database.driverClassName>com.mysql.jdbc.Driver</database.driverClassName> <database.url>jdbc:mysql://master01:3306,slave01:3306/app_prod</database.url> <database.user>prod_user</database.user> </properties> </profile> </profiles> In such cases, you can activate the profile by running dev mvn clean install -Denvironemtn.type=dev Common Maven Commands When using Maven it is good to know the common Maven commands that you will be using day to day. A few of the most important ones that I am using day to day are listed below. Display Maven version → mvn -v mvn --version Getting help→ mvn -h mvn --help To build a Maven artifact → mvn clean install To build a Maven artifact without running tests → mvn clean install -Dmaven.test.skip=true mvn clean install -DskipTests To run Maven with a profile (e.g., profile) → production mvn clean install -Pproduction Profile activation with variables → mvn clean install -Denvironment.type=dev Listing the active profiles → mvn help:active-profiles To run Maven with debug enabled → mvn clean install -X mvn clean install --debug To view the effective POM → mvn help:effective-pom To view the dependency tree → mvn dependency:tree To view execution error messages with full stack trace → mvn -e clean install mvn --errors clean install To only show error messages → mvn -q clean install mvn --quiet clean install Run Maven in offline mode → mvn -o clean install Making a subset of projects → The projects that were mentioned will be built. mvn --projects <project_name_1>,<project_name_2> --also-make install mvn -pl <project_name_1>,<project_name_2> -am install Making project dependents → The mentioned projects and their dependents will be built. mvn --projects <project_name_1>,<project_name_2> --also-make-dependents install mvn -pl <project_name_1>,<project_name_2> --amd install Resuming a project → If you have built a few modules of a project and need to continue with other submodules, you can use this. mvn --resumt-from <project_name> install mvn -rf <project_name> install Describe a Maven plugin → mvn help:describe -Dplugin=help -Dfull mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin Describe the plugin with goals → mvn help:describe -Dcmd=compiler:compiler More information on the available configuration parameters → mvn help:describe -Dcmd=compiler:compile -Ddetail So, this is it! Check out my previous on Medium if you want to know how to use Maven with Windows! (This is the original article, this article was based upon. 🙃) If you want to know all about Maven, check out by Most of the concepts I have described here are mentioned thoroughly in this book. article on Maven Maven: The Complete Reference SonaType. I have not mentioned about in this article, since it is a heavy topic. But if you are interested in learning about check out the below link. plugins Maven Plugins, https://maven.apache.org/guides/plugin/guide-java-plugin-development.html Cheers!