Maven
Maven is a project Management Tool that can
            Manage source code
            Testing
            Manage the project Structure
            Manage Libraries/Dependencies
            Manage Configurations
            Task Runner - build, test, run
            Reporting
        Maven does it using the Project Object Model. Maven is an open source Apache
        project
        It provides project structure and manages contents and it helps manage
        dependencies
        Maven simplifies and standardises the project build process. It handles compilation,
        distribution, documentation, team collaboration and other tasks seamlessly. Maven
        increases reusability and takes care of most of the build related tasks.
        Characteristics
            Convention over Configuration
            Consistent
            Configurable
            IDE Agnostic
            IDE Supported
            Declarative dependency management
            Plugin based architecture
Maven                                                                                          1
        As an example, following table shows the default values for project source code files,
        resource files and other configurations. Assuming, ${basedir} denotes the project
        location −
         Item                                      Default
         source code                               ${basedir}/src/main/java
         Resources                                 ${basedir}/src/main/resources
         Tests                                     ${basedir}/src/test
         Complied byte code                        ${basedir}/target
         distributable JAR                         ${basedir}/target/classes
        For example, Maven expects your code under src/main/java , but if you want to
        change this format, you can change it as well and Maven will configure it accordingly.
        Maven POM
        The POM contains information about the project and various configuration detail
        used by Maven to build the project(s).
        POM also contains the goals and plugins. While executing a task or goal, Maven
        looks for the POM in the current directory. It reads the POM, gets the needed
        configuration information, and then executes the goal. Some of the configuration that
        can be specified in the POM are following −
            project dependencies
            plugins
            goals
            build profiles
            project version
            developers
            mailing list
        It should be noted that there should be a single POM file for each project.
Maven                                                                                            2
            All POM files require the project element and three mandatory fields: groupId,
            artifactId, version.
            Projects notation in repository is groupId:artifactId:version.
            Minimal requirements for a POM
        Super POM
        The Super POM is Maven’s default POM. All POMs inherit from a parent or default
        (despite explicitly defined or not). This base POM is known as the Super POM, and
        contains values inherited by default.
        Maven use the effective POM (configuration from super pom plus project
        configuration) to execute relevant goal. It helps developers to specify minimum
        configuration detail in his/her pom.xml. Although configurations can be overridden
        easily.
        An easy way to look at the default configurations of the super POM is by running the
        following command: mvn help:effective-pom
        Maven - Project Templates
        Maven has the ability to create the project for you based on the conventional
        template, called archetypes.
        mvn archetype:generate
        What is Archetype?
        Archetype is a Maven plugin whose task is to create a project structure as per its
        template. We are going to use quickstart archetype plugin to create a simple java
        application here.
        Maven gets a huge list of projects form which we need to choose.
        GroupId - Analogous to package name. Let’s say someone working for Google, will
        have groupId as com.Google
Maven                                                                                          3
        ArtifactId - What is the current maven project about ? Weather app, Calculator app
        ?
        version - Changes made during the project lifecycle, updates the version. We start
        with 1.0.0
        How did Maven create the project using Archetype ?
        The machine doesn’t have a project. Maven gets that information from repository
        repo1.maven.apache.org (This is the central repository). You can change this
        repository.
        This repository has these archetypes that you can choose for maven.
        Repository returns a list of items and then we choose one, which maven downloads
        and creates a project which is based on this template.
        Project Structure
        src
              main
                 java
                     io
                          javabrains
                             App.java
              test
                 java
                     io
                          javabrains
                             AppTest.java
        pom.xml
        How are naming artifacts/ version related conflicts avoided ?
Maven                                                                                        4
        GroupId, ArtifactId, Version and Packaging together form a maven coordinate. A
        maven coordinate has to be unique. Maven coordinates are specified in pom.xml
        Version is the one that causes changes to be made. So, with a new version a new
        jar is generated
        Maven compile command - mvn compile. Maven puts the compiled files(class files)
        into a folder called target.
        target/classes/App.class
        Every maven project has a lifecycle.
        To run a maven test use the command - mvn test
        To generate a jar/war from maven use the command - mvn package
        The jar file gets created under the target folder
        After we make new changes, we just need to change the version and do a jar build,
        another jar will be created under the target folder with the new version number.
        Dependency Management
        Maven remote repo contains repository of archetypes and artifacts.
        One way to download libraries is to go get the jar file and add to classpath, which is
        error prone and tedious.
        Other way is declarative dependency management. We specify the list of
        dependencies with version(maven coordinates). Maven gets the artifacts from the
        repository and makes them available, just by getting the entries from the pom.xml.
        Dependencies section is present in pom.xml. This is where we declare list of
        dependencies that we require maven to fetch.
        After adding a dependency, mvn compile needs to be run for maven to get the
        dependency. We don’t get to observe this in IDE, as it all happens behind the scene.
Maven                                                                                            5
        Transitive Dependencies
        Let’s say we have 2 dependencies A and B
        Now, A and B are artifacts themselves, so they have dependencies of their own.
        A→C
        For A to work, we need C.
        Maven downloads C’s dependencies.
        A is a direct dependency, C is a transitive dependency
        Now, consider the scenario
        Project has two dependencies, A and B
        A → B(3.0)
        B(2.0)
        Now, maven cannot download both 2.0 and 3.0
        Maven will follow dependency mediation.
            Nearest Definition - 2.0 is nearer to 1.0, so it will download B(2.0)
            First Declaration - Get the first declaration
        What if we want to override, we declare the required dependency directly.
        Dependency Scope
        Maven - Snapshots
        Consider a team is working on the front end of the application as app-ui project (app-
        ui.jar:1.0) and they are using data-service project (data-service.jar:1.0).
        Now it may happen that team working on data-service is undergoing bug fixing or
        enhancements at rapid pace and they are releasing the library to remote repository
        almost every other day.
        Now if data-service team uploads a new version every other day, then following
        problems will arise −
Maven                                                                                            6
            data-service team should tell app-ui team every time when they have released
            an updated code.
            app-ui team required to update their pom.xml regularly to get the updated
            version.
        To handle such kind of situation, SNAPSHOT concept comes into play.
        If a version is SNAPSHOT, then maven waits for a day and gets a newer version.
        For example 2.1.0 - SNAPSHOT
        SNAPSHOT is a special version that indicates a current development copy. Unlike
        regular versions, Maven checks for a new SNAPSHOT version in a remote
        repository for every build.
        Now data-service team will release SNAPSHOT of its updated code every time to
        repository, say data-service: 1.0-SNAPSHOT, replacing an older SNAPSHOT jar.
        Snapshot vs Version
        In case of Version, if Maven once downloaded the mentioned version, say data-
        service:1.0, it will never try to download a newer 1.0 available in repository. To
        download the updated code, data-service version is be upgraded to 1.1.
        In case of SNAPSHOT, Maven will automatically fetch the latest SNAPSHOT (data-
        service:1.0-SNAPSHOT) every time app-ui team build their project.
        What happens if dependency is not available in any of remote repositories and
        central repository? Maven provides answer for such scenario using concept
        of External Dependency.
        For example, let us do the following changes to the project created in ‘Creating Java
        Project’ chapter.
            Add lib folder to the src folder.
            Copy any jar into the lib folder. We've used ldapjdk.jar, which is a helper library
            for LDAP operations.
        Here you are having your own library, specific to the project, which is an usual case
        and it contains jars, which may not be available in any repository for maven to
Maven                                                                                             7
        download from. If your code is using this library with Maven, then Maven build will
        fail as it cannot download or refer to this library during compilation phase.
        To handle the situation, let's add this external dependency to maven pom.xml using
        the following way.
          <dependency>
                   <groupId>ldapjdk</groupId>
                   <artifactId>ldapjdk</artifactId>
                   <scope>system</scope>
                   <version>1.0</version>
                   <systemPath>${basedir}\src\lib\ldapjdk.jar</systemPath>
                </dependency>
        Maven Architecture in Enterprise
        Enterprises may create artifacts that are not publicly available. So, these internal
        artifacts are kept in a local maven repository. This local repository acts a cache. So,
        the setting would be to contact the local repository and not the central repository.
        If an artifact is not available, maven will contact the global repository and add it to
        the local repository cache.
        You can also publish your artifact, so that you can use it in another project.
        This works by using the command - mvn install
        Maven Build Lifecycle
        A Build Lifecycle is a well-defined sequence of phases, which define the order in
        which the goals are to be executed. Here phase represents a stage in life cycle. As
        an example, a typical Maven Build Lifecycle consists of the following sequence of
        phases.
            Validate
            Compile
            Test
            Package
Maven                                                                                             8
            Verify
            Install
            Deplo
        Maven has the following three standard lifecycles −
            clean
            default(or build)
            site
        A goal represents a specific task which contributes to the building and managing of
        a project. It may be bound to zero or more build phases. A goal not bound to any
        build phase could be executed outside of the build lifecycle by direct invocation.
        The order of execution depends on the order in which the goal(s) and the build
        phase(s) are invoked. For example, consider the command below.
        The clean and package arguments are build phases while the dependency:copy-
        dependencies is a goal.
         mvn clean dependency:copy-dependencies package
        Here the clean phase will be executed first, followed by the dependency:copy-
        dependencies goal, and finally package phase will be executed.
        mvn clean
        mvn site - Generates reports related to dependencies, plugins, project management
        Maven Plugins
        Maven is actually a plugin execution framework where every task is actually done by
        plugins. Maven Plugins are generally used to −
            create jar file
Maven                                                                                         9
            create war file
            compile code files
            unit testing of code
            create project documentation
            create project reports
        A plugin generally provides a set of goals, which can be executed using the following
        syntax −
          mvn [plugin-name]:[goal-name]
        For example, a Java project can be compiled with the maven-compiler-plugin's
        compile-goal by running the following command.
          mvn compiler:compile
        Plugin Types
        Maven provided the following two types of Plugins
            Plugins are specified in pom.xml using plugins element.
            Each plugin can have multiple goals.
            You can define phase from where plugin should starts its processing using its
            phase element. We've used clean phase.
            You can configure tasks to be executed by binding them to goals of plugin.
            We've bound echo task with run goal of maven-antrun-plugin.
            Maven will then download the plugin if not available in local repository and start
            its processing.
        Maven Repository
        A repository is a directory where all the project jars, library jar, plugins or any other
        project specific artifacts are stored and can be used by Maven easily.
Maven                                                                                               10
        Maven repository are of three types. The following illustration will give an idea
        regarding these three types.
            local
            central
            remote
        Local Repository
        Maven local repository is a folder location on your machine. It gets created when you
        run any maven command for the first time.
        Maven local repository keeps your project's all dependencies (library jars, plugin jars
        etc.). When you run a Maven build, then Maven automatically downloads all the
        dependency jars into the local repository. It helps to avoid references to
        dependencies stored on remote machine every time a project is build.
        Maven maintains cache locally, so each time it does not contact the remote
        repository. It’s present in .m2 directory.
        Maven local repository by default get created by Maven in %USER_HOME%
        directory. To override the default location, mention another path in Maven
        settings.xml file available at %M2_HOME%\conf directory.
        Central Repository
Maven                                                                                             11
        Maven central repository is repository provided by Maven community. It contains a
        large number of commonly used libraries.
        When Maven does not find any dependency in local repository, it starts searching in
        central repository using following URL − https://repo1.maven.org/maven2/
        Key concepts of Central repository are as follows −
            This repository is managed by Maven community.
            It is not required to be configured.
            It requires internet access to be searched.
        Remote Repository
        Sometimes, Maven does not find a mentioned dependency in central repository as
        well. It then stops the build process and output error message to console. To prevent
        such situation, Maven provides concept of Remote Repository, which is developer's
        own custom repository containing required libraries or other project jars.
        For example, using below mentioned POM.xml, Maven will download dependency
        (not available in central repository) from Remote Repositories mentioned in the
        same pom.xml.
        Maven Dependency Search Sequence
        When we execute Maven build commands, Maven starts looking for dependency
        libraries in the following sequence −
            Step 1 − Search dependency in local repository, if not found, move to step 2 else
            perform the further processing.
            Step 2 − Search dependency in central repository, if not found and remote
            repository/repositories is/are mentioned then move to step 4. Else it is
            downloaded to local repository for future reference.
            Step 3 − If a remote repository has not been mentioned, Maven simply stops the
            processing and throws error (Unable to find dependency).
            Step 4 − Search dependency in remote repository or repositories, if found then it
            is downloaded to local repository for future reference. Otherwise, Maven stops
            processing and throws error (Unable to find dependency).
Maven                                                                                           12