Maven
August 1, 2017

References

Maven Build Lifecycle

  1. Validate: validate the project and its information
  2. Compile: compile the source code
  3. Test: compile test code and run tests
  4. Package: package the project into jar or war (or other compressed) files
  5. Verify: verify results of integration tests
  6. Install: install the files in ‘package’ stage to a local repository
  7. Deploy: deploy the packages to a remote repository for sharing with other developers

When you run a command such as mvn [phase] , Maven will execute all phases from validate to the specified [phase]

How to install maven with brew but without openjdk

1
2
3
4
brew install --cask temurin17
cd /usr/local/opt
ln -s /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home openjdk
brew install --ignore-dependencies maven

Sending or overriding parameters to pom

-D option is to send parameter value to the pom, or to override the values in ~/.m2/settings.xml.

1
$ mvn exec:exec -DcustomerId=1234 -Doutcome=REJECTED -DserviceUrl=http://localhost:8080/services/soap

Skipping tests, gpg and javadoc

1
$ mvn clean install -DskipTests -Dgpg.skip -Dmaven.javadoc.skip=true

Maven Dependency Graph

Open pom.xml and go to the Graph tab to see dependency graph.

Creating maven archetypes

Generate the base-archetype

cd into the project directory (or, in the case of a multi-module project, cd into the parent/aggregator project) and run the following command:

1
2
$ mvn archetype:create-from-project
$ mvn clean

This will generate a bulk of files and folders under the target/generated-sources/archetype directory: From the folder structure you can discard the target directory sub-tree, just mvn clean it.

1
2
$ cd target/generated-sources/archetype
$ tree -d
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
.
└── src
    ├── main
    │   └── resources
    │       ├── META-INF
    │       │   └── maven
    │       └── archetype-resources
    │           └── src
    │               └── main
    │                   ├── java
    │                   └── webapp
    │                       └── WEB-INF
    └── test
        └── resources
            └── projects
                └── basic

Adjusting the archetype

  • ${rootArtifactId} to rename variables, methods, comments, etc that depends on the supplied project name.
  • __rootArtifactId__ to rename files/folders.

How to add a local library to a maven project in NetBeans?

  1. Right-click on the “Dependencies” folder in the Projects view
  2. Enter some groupId, artifactId and version information
  3. Dependency will be added to the pom.xml and will appear under “Libraries” node of maven project
  4. Right-click lib node and “manually install artifact”, fill the path to the jar
  5. Jar should be installed to local Maven repo with coordinates entered in step 2

Netbeans will issue the following mvn command behind the scenes

1
mvn -DartifactId={artifact id} -DgroupId={group id} -Dversion={version} -Dpackaging=jar -Dfile={path to jar} -DgeneratePom=false install:install- file

Inject Maven project informations into Java application

http://ovaraksin.blogspot.com.tr/2012/02/inject-maven-project-informations-into.html

Install local jar with the maven-install-plugin

http://www.baeldung.com/install-local-jar-with-maven/

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <version>2.5.2</version>
            <configuration>
                <groupId>net.sf.barcode4j</groupId>
                <artifactId>barcode4j-light</artifactId>
                <version>2.1</version>
                <packaging>jar</packaging>
                <file>${basedir}/dependencies/barcode4j-light.jar</file>
                <generatePom>true</generatePom>
            </configuration>
            <executions>
                <execution>
                    <id>install-jar-lib</id>
                    <goals>
                        <goal>install-file</goal>
                    </goals>
                    <phase>validate</phase>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Suppressing GPG signing for Maven builds

Add gpg plugin in a profile as below and then when you need to do a release, add the property to your mvn command:

1
mvn -DperformRelease=true ...
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<profiles>
  <profile>
    <id>release-sign-artifacts</id>
    <activation>
      <property>
        <name>performRelease</name>
        <value>true</value>
      </property>
    </activation>
    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-gpg-plugin</artifactId>
          <version>1.6</version>
          <executions>
            <execution>
              <id>sign-artifacts</id>
              <phase>verify</phase>
              <goals>
                <goal>sign</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>
  </profile>
</profiles>

OSSRH Sonatype Nexus

Maven always uses either one or two settings files. The global settings defined in ${M2_HOME}/conf/settings.xml is always required. The user settings file defined in ${user.home}/.m2/settings.xml is optional. Any settings defined in the user settings take precedence over the corresponding global settings.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
  <servers>
    <server>
      <id>gpg.passphrase</id>
      <passphrase>P@assphrase123</passphrase>
    </server>
  </servers>
</settings>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# pom.xml
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-gpg-plugin</artifactId>
      <version>1.6</version>
      <executions>
          <execution>
              <id>sign-artifacts</id>
              <phase>verify</phase>
              <goals>
                  <goal>sign</goal>
              </goals>
          </execution>
      </executions>
    </plugin>
  </plugins>
</build>

First if you do not have one, you need to create a key. To generate a key pair

1
gpg --gen-key

List all available keys

1
gpg --list-keys

and send key to pool.sks-keyservers.net server

1
gpg --keyserver hkp://pool.sks-keyservers.net --send-keys [key]

To check the configuration

1
mvn clean verify

Possible errors you will get are

gpg: signing failed: Inappropriate ioctl for device

Add below line to ~/.bash_profile or ~/.zshrc

1
2
GPG_TTY=$(tty)
export GPG_TTY

and reload your .zshrc

1
source ~/.zshrc

or

1
. ~/.zshrc

gpg: keyserver receive failed: No route to host

List all available gpg servers

1
gpg-connect-agent --dirmngr 'keyserver --hosttable'

and select and use an active server in order to send or receive key

1
2
3
4
5
gpg --keyserver hkp://keys.openpgp.org --send-keys [key]
gpg --keyserver hkp://keys.openpgp.org --recv-keys [key]

gpg --keyserver hkp://pgp.mit.edu --send-keys [key]
gpg --keyserver hkp://pgp.mit.edu --recv-keys [key]

git commit signing failed: secret key not available

You need to configure the secret key before using it.

1
git config user.signingkey 35F5FFB2

Or declare it globally if you want to use the same key for every repository.

1
git config --global user.signingkey 35F5FFB2

maven-glassfish-plugin

To deploy your application using Maven, create the settings.xml file under the .m2 folder, providing the glassfish profile credentials: they will automatically imported in the pom.xml file.

in your pom.xml file add

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<build>
  <plugins>
    <plugin>
      <groupId>org.glassfish.maven.plugin</groupId>
      <artifactId>maven-glassfish-plugin</artifactId>
      <version>2.1</version>
      <configuration>
        <glassfishDirectory>${glassfish.home}</glassfishDirectory>
        <user>admin</user>
        <!--<adminPassword>${glassfish.adminPassword}</adminPassword>-->
        <passwordFile>${glassfish.passfile}</passwordFile>
        <domain>
          <name>domain1</name>
          <httpPort>8080</httpPort>
          <adminPort>4848</adminPort>
        </domain>
        <components>
          <component>
            <name>${project.artifactId}</name>
            <artifact>target/${project.build.finalName}.war</artifact>
          </component>
        </components>
        <debug>true</debug>
        <terse>false</terse>
        <echo>true</echo>
      </configuration>
    </plugin>
  </plugins>
</build>

and then run

1
$ mvn clean package glassfish:deploy

wildfly-maven-plugin

in your pom.xml file add

1
2
3
4
5
6
7
8
9
<build>
  <plugins>
    <plugin>
      <groupId>org.wildfly.plugins</groupId>
      <artifactId>wildfly-maven-plugin</artifactId>
      <version>2.0.0.Final</version>
    </plugin>
  </plugins>
</build>

and then run

1
$ mvn clean wildfly:deploy

exec-maven-plugin

to backup mysql database for example, add below lines in your pom.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <version>1.2.1</version>
      <executions>
        <execution>
          <id>default-cli</id>
          <goals>
            <goal>exec</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <executable>/usr/bin/mysqldump</executable>
        <workingDirectory>/tmp/${database.schema}</workingDirectory>
        <commandlineArgs>${database.schema} --host ${database.host} --user=${database.username} --password=${database.password} --result-file=${env.name}_${database.schema}_backup.sql</commandlineArgs>
      </configuration>
    </plugin>
  </plugins>
</build>

and then run

1
$ mvn exec:exec -Pproduction

maven-clean-plugin

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-clean-plugin</artifactId>
    <version>3.2.0</version>
    <configuration>
        <filesets>
            <fileset>
                <directory>${basedir}/data</directory>
            </fileset>
            <fileset>
                <directory>${basedir}/</directory>
                <includes>
                    <include>**/*.dmg</include>
                    <include>**/*.tmp</include>
                    <include>**/*.log</include>
                </includes>
                <excludes>
                    <exclude>**/important.log</exclude>
                    <exclude>**/another-important.log</exclude>
                </excludes>
                <followSymlinks>false</followSymlinks>
            </fileset>
        </filesets>
    </configuration>
</plugin>

Dependency tree

1
mvn dependency:tree

Check new version of the dependencies

1
mvn versions:display-dependency-updates

mvn:deploy

This runs through the whole build life cycle and therefore performs the following tasks:

  • compile main and test Java code
  • run tests
  • create a Java archive JAR with the compiled code and resources
  • create a JAR containing the source code
  • create JavaDoc HTML files
  • create a JAR containing JavaDocs
  • sign all artifacts with GPG
  • install them to the local repository

The version number determines the deployment target. Any version number ending in -SNAPSHOT is deployed to the OSSRH snapshot repository. The exact URL including the path from the groupId, artifactId and version is e.g. https://oss.sonatype.org/content/repositories/snapshots/com/aripd/component/1.6-SNAPSHOT/.

Any other version number constitutes a release and is deployed to a OSSRH staging repository for potential synchronization to the Central Repository. You can log into OSSRH, verify the components and manually release them as desired.

The actual invocation used in the Pipelines script is

1
mvn -V -B -s settings.xml deploy

The -V options triggers an output of the Maven and Java versions at the beginnging of the build. The -B option suppresses the download progress logging for each required artifact. The -s settings.xml configuration causes the usage of the local settings with the required credentials.