Maven

Books, articles

Maven References to quick schemas and tags

Installing

Linux

Can install from package manager on Ubuntu but to get a newer version you can download + install

# may need sudo for some commands
$ wget https://downloads.apache.org/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz -P /tmp
$ tar xvf /tmp/apache-maven-3.6.3-bin.tar.gz -C /opt
$ ln -s /opt/apache-maven-3.6.3 /opt/maven

# Possibly permissions update 
sudo chmod -R ugo+rx /opt/apache-maven-3.8.4/

# Set in ~./profile as Maven home and export to path
# export MAVEN_HOME="/opt/maven"
# export PATH=${MAVEN_HOME}/bin:${PATH}
source ~/.profile 
  Newer version 
  https://downloads.apache.org/maven/maven-3/3.8.8/binaries/apache-maven-3.8.8-bin.tar.gz

POM Reference - excluding Dependencies

Exclusions

Exclusions explicitly tell Maven that you don't want to include the specified project that is a dependency of this dependency (in other words, its transitive dependency). For example, the maven-embedder requires maven-core, and we do not wish to use it or its dependencies, then we would add it as an exclusion.

<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">
    ...
    <dependencies>
      <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-embedder</artifactId>
        <version>2.0</version>
        <exclusions>
          <exclusion>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-core</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      ...
    </dependencies>
    ...

</project>

It is also sometimes useful to clip a dependency's transitive dependencies. A dependency may have incorrectly specified scopes, or dependencies that conflict with other dependencies in your project. Using wildcard excludes makes it easy to exclude all a dependency's transitive dependencies. In the case below you may be working with the maven-embedder and you want to manage the dependencies you use yourself, so you clip all the transitive dependencies:

<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">
    ...
    <dependencies>
      <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-embedder</artifactId>
        <version>3.1.0</version>
        <exclusions>
          <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      ...
    </dependencies>
    ...

</project>
  • exclusions:
    • Exclusions contain one or more exclusion elements, each containing a groupId and artifactId denoting a dependency to exclude. Unlike optional, which may or may not be installed and used, exclusions actively remove themselves from the dependency tree.

Maven plugin for JaxB

Welcome to the org.jvnet.jaxb2.maven2:maven-jaxb2-plugin, the most advanced and feature-full Maven plugin for XML Schema compilation.

This Maven plugin wraps and enhances the JAXB Schema Compiler (XJC) and allows compiling XML Schemas (as well as WSDL, DTDs, RELAX NG) into Java classes in Maven builds.

Maven Goals and Phases

Basic idea: Maven has build lifecycle made of phases, which are made up of goals.

  • validate: check if all information necessary for the build is available
  • compile: compile the source code
  • test-compile: compile the test source code
  • test: run unit tests
  • package: package compiled source code into the distributable format (jar, war, …)
  • integration-test: process and deploy the package if needed to run integration tests
  • install: install the package to a local repository
  • deploy: copy the package to the remote repository

Maven Assembly plugin

Can be used to build executable jars, zips etc. In general can be replaced by the maven shadow plugin for building an "uberjar" but helpful for building a zip containing all code - tests and main classes for example which shadow can't do.

NB - normal phase is package, install is for a particular project need.


mvn org.apache.maven.plugins:maven-assembly-plugin:2.3:single
    -Dassembly.appendAssemblyId=false
    -Ddescriptor=src/main/assembly/assembly_uberjar.xml
    -DfinalName=gatling

mvn org.apache.maven.plugins:maven-assembly-plugin:2.3:single
    -Dassembly.appendAssemblyId=false
    -Ddescriptor=src/main/assembly/assembly_zip.xml
    -DfinalName=gatlingCommandLine

    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <version>2.3</version>
      <executions>
          <execution>
              <id>make-assembly-uberjar</id>
              <phase>install</phase>
              <goals>
                  <goal>single</goal>
              </goals>
              <configuration>
                  <descriptor>src/main/assembly/assembly_uberjar.xml</descriptor>
                  <finalName>gatling</finalName>
                  <appendAssemblyId>false</appendAssemblyId>
              </configuration>
          </execution>
          <execution>
              <id>make-assembly-zip</id>
              <phase>install</phase>
              <goals>
                  <goal>single</goal>
              </goals>
              <configuration>
                  <descriptor>src/main/assembly/assembly_zip.xml</descriptor>
                  <finalName>gatlingCommandLine</finalName>
                  <appendAssemblyId>false</appendAssemblyId>
              </configuration>
          </execution>
      </executions>
    </plugin>

Maven copy dependencies plugin

NB - normal phase is package, install is for a particular project need.

mvn org.apache.maven.plugins:maven-dependency-plugin:3.1.2:copy-dependencies
    -DoutputDirectory=../DCRepo
    -Dmdep.useRepositoryLayout=true
    -Dmdep.copyPom=true -DoverWriteIfNewer=true
<plugin>

  <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <version>3.1.2</version>
      <executions>
          <execution>
              <id>copy-dependencies</id>
              <phase>install</phase>
              <goals>
                  <goal>copy-dependencies</goal>
              </goals>
              <configuration>
                  <outputDirectory>../DCRepo</outputDirectory>
                  <useRepositoryLayout>true</useRepositoryLayout>
                  <copyPom>true</copyPom>
                  <overWriteReleases>false</overWriteReleases>
                  <overWriteSnapshots>false</overWriteSnapshots>
                  <overWriteIfNewer>true</overWriteIfNewer>
              </configuration>
          </execution>
      </executions>
  </plugin>

Maven Build Helper plugin

Can be useful to "add" sources or tests to the list of files to be considered for a compile. Works in a "generate-sources" phase before the build.

I've made use of it in a profile to add back an excluded source to the build.

Maven Profiles

You can build differently depending on the required context - e.g. environment diffs etc.

# Basic usage
mvn groupId:artifactId:goal -P profile-1,profile-2,?profile-3
mvn clean package -P build_for_test

Multi Module project

Options for plugins

From the maven docs it can be difficult to work out what the command line options are, especially when the xml and command line formats are slightly different. Checking the source code can give you the definitive guide to what to use:


# Run a single named test from mvn
mvn gatling:test -Dgatling.simulationClass=org.blah.SomeGatlingSimulationClassName

# Enable multiple simulations to be run from gatling mvn plugin - could also do on command line I think:
# <configuration>
#   <runMultipleSimulations>true</runMultipleSimulations>
# </configuration>

Example of skipping Dependency analysis

# https://maven.apache.org/plugins/maven-dependency-plugin/analyze-mojo.html#skip
mvn -Dmdep.analyze.skip=true clean deploy

Checking Maven Dependencies

# Can check for problems with dependencies
$ mvn dependency:analyze
$ mvn dependency:tree
        ....
        [INFO] com.restapi:msproducts:jar:0.0.1-SNAPSHOT
        [INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:2.2.6.RELEASE:compile
        [INFO] |  +- org.springframework.boot:spring-boot-starter-aop:jar:2.2.6.RELEASE:compile
        [INFO] |  |  +- org.springframework:spring-aop:jar:5.2.5.RELEASE:compile
        [INFO] |  |  \- org.aspectj:aspectjweaver:jar:1.9.5:compile
        [INFO] |  +- org.springframework.boot:spring-boot-starter-jdbc:jar:2.2.6.RELEASE:compile
        [INFO] |  |  +- com.zaxxer:HikariCP:jar:3.4.2:compile
        [INFO] |  |  \- org.springframework:spring-jdbc:jar:5.2.5.RELEASE:compile
        [INFO] |  +- jakarta.activation:jakarta.activation-api:jar:1.2.2:compile
        [INFO] |  +- jakarta.persistence:jakarta.persistence-api:jar:2.2.3:compile
        [INFO] |  +- jakarta.transaction:jakarta.transaction-api:jar:1.3.3:compile
        [INFO] |  +- org.hibernate:hibernate-core:jar:5.4.12.Final:compile
# Can filter to search for or exclude dependencies
$ mvn dependency:tree -Dincludes=org.projectlombok

        [INFO] --- maven-dependency-plugin:3.1.2:tree (default-cli) @ msproducts ---
        [INFO] com.restapi:msproducts:jar:0.0.1-SNAPSHOT
        [INFO] \- org.projectlombok:lombok:jar:1.18.12:compile (optional)

$ mvn dependency:tree -Dexcludes=org.springframework.*,org.projectlombok

Also more here -

MVND - a Maven daemon for building in parallel to speed up compile

Maven logging

mvn --log-file ./mvn.log clean compile

Testing

Maven Surefire plugin - running tests

Running a single test from commandline

# Run a single test in a test class from mvn
mvn -Dtest=TestApp#testMethod test