Maven command line usage

Figure 276. CLI example Slide presentation
mvn --batch-mode -e archetype:generate \
-DgroupId=de.hdm_stuttgart.mi.sd1 -DartifactId=second -Dversion=0.9 \
-DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4

[INFO] Scanning for projects...
      ...
[INFO] BUILD SUCCESS ...

See artifact reference.


The MI department provides modified archetypes supporting more current versions of unit testing software. These are being provided by a Maven repository server:

Figure 277. Supplementary MI Maven archetypes Slide presentation

Create an empty .m2 Maven configuration and caching related directory below your home directory ~. The -p option avoids an error message in case ~/.m2 already exists.

Use a text editor like nano, vim, emacs, IntelliJ,... for creating the following (presumably new) file ~/.m2/settings.xml:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

  <profiles>
    <profile>
      <id>development</id>
      <repositories>
        <repository>
          <id>miSupplementaryMavenStuff</id>
          <name>Supplementary MI archetypes and artifacts</name>

          <!-- The actual »payload« referring to the MI Maven server hosting additional archetypes and artifacts -->
          <url>https://maven.mi.hdm-stuttgart.de/nexus/repository/mi-maven</url>

          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </repository>
      </repositories>
    </profile>
  </profiles>

  <activeProfiles>
    <activeProfile>development</activeProfile>
  </activeProfiles>

</settings>

Note

https://maven.mi.hdm-stuttgart.de/nexus/repository/mi-maven refers to a Sonatype Nexus repository manager instance hosting supplementary Maven archetypes and artifacts.


Figure 278. CLI testing mi-maven-archetype-quickstart Slide presentation
mvn --batch-mode -e archetype:generate \
  -DgroupId=de.hdm_stuttgart.mi.sd1 -DartifactId=second -Dversion=0.9 \
  -DarchetypeGroupId=de.hdm_stuttgart.mi -DarchetypeArtifactId=mi-maven-archetype-quickstart -DarchetypeVersion=2.3
[INFO] Error stacktraces are turned on.
[INFO] Scanning for projects...
      ...
[INFO] BUILD SUCCESS ...

Figure 279. CLI archetype details Slide presentation
mvn --batch-mode  -e archetype:generate  \
                                              \
 -DarchetypeGroupId=de.hdm_stuttgart.mi \ 
 -DarchetypeArtifactId=mi-maven-archetype-quickstart \
 -DarchetypeVersion=2.3 \
                        \
 -DgroupId=de.hdm_stuttgart.mi.sd1  \
 -DartifactId=first  \
 -Dversion=0.9

During project generation Maven shall work in batch mode not asking for user input.

Create a Maven project using an archetype being specified by .

Our desired archetype is being addressed by its three »coordinates« on the MI Maven repository server:

archetypeGroupId

de.hdm_stuttgart.mi typically referring to the hosting institution.

archetypeArtifactId

mi-maven-archetype-quickstart denoting a piece of software within a hosting institution.

archetypeVersion

2.3 identifying a specific version of the software in question.

Likewise we do have three parameters uniquely defining our own software product's Maven identity:

  • groupId. This value also defines the projects base package name as being explained in the section called “Packages”:

    package de.hdm_stuttgart.mi.sd1;
    ...
    public class ...

    Note

    You must not use operator symbols like - in groupId definitions. For this reason the current example features de.hdm_stuttgart.mi.sd1 rather than de.hdm-stuttgart.mi.sd1.

  • artifactId

  • version


Figure 280. Generated project layout Slide presentation
> cd first        # Enter project directory
> find . -type f  # Search recursively for files
./pom.xml 
./src/main/java/de/hdm_stuttgart/mi/sd1/HighlightSample.java
./src/main/java/de/hdm_stuttgart/mi/sd1/Statistics.java
./src/main/java/de/hdm_stuttgart/mi/sd1/App.java  
./src/main/resources/log4j2.xml
./src/test/java/de/hdm_stuttgart/mi/sd1/AppTest.java
./Readme.md

The Project Object Model file defining build rules.

Java source file containing an executable main() class.


exercise No. 116

DNS inflicted groupId / package names clashes

Q:

Regarding the extended explanations of Figure 279, “CLI archetype details ” we consider two different organisations https://hdm-stuttgart.de and https://hdm_stuttgart.de. Following the »coordinate« recommendations both organizations would then choose the common conflicting groupId de.hdm_stuttgart leading to possible Maven artifact clashes. May this conflict actually happen?

Tip

Read about valid DNS domain names.

A:

The conflict cannot occur since the underscore is being disallowed in domain names according to the DNS specification. Thus hdm_stuttgart.de is an illegal domain name. Mapping hyphens appearing in domain names to underscores in packages therefore works perfectly.

Figure 281. Maven compile Slide presentation
> mvn compile
[INFO] Scanning for projects...
       ...
[INFO] Building first 0.9
   ...
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /ma/goik/first/target/classes
[INFO] --------------------------------------------------------
[INFO] BUILD SUCCESS

Figure 282. Compilation file view Slide presentation
> find target/classes -type f
./target/classes/de/hdm_stuttgart/mi/sd1/App.class
...

Figure 283. Execution Slide presentation
> cd target/classes 
> java de.hdm_stuttgart.mi.sd1.App 
Hi there, let's have
fun learning Java! 

Change to base directory containing compiled Java classes.

Application execution. Note:

Our App class is being prefixed by the package name de.hdm_stuttgart.mi.sd1 defined by the groupId parameter in Figure 279, “CLI archetype details ”.

The expected output result.

Note

Executing this particular class requires a configuration in our project's pom.xml file:

...
<archive>
  <manifest>
    <mainClass>de.hdm_stuttgart.mi.sd1.test.ShowReachedPoints</mainClass>
  </manifest>
</archive> ...

Figure 284. Maven package Slide presentation
> mvn package
...
 T E S T S
...
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
   ...
[INFO] Building jar: /ma/goik/first/target/first-0.9.jar
...
[INFO] Replacing /ma/goik/first/target/first-0.9.jar with 
         /ma/goik/first/target/first-0.9-shaded.jar
...
[INFO] BUILD SUCCESS

Figure 285. Executing Java archive first-0.9.jar Slide presentation
java -jar target/first-0.9.jar
Hi there, let's have
fun learning Java!

Remark: This will execute HelloWorld.class being contained in first-0.9.jar.


exercise No. 117

Details on execution

Q:

In Figure 285, “Executing Java™ archive first-0.9.jar we saw successful execution of:

java -jar target/first-0.9.jar

How does this actually work? There might be multiple executable classes containing main() methods within a given project? How is de/hdm_stuttgart/mi/sd1/App.class being selected for execution?

Tip

Have a closer look on your project's pom.xml. Also unzip your generated first-0.9.jar file to examine the contained file META-INF/MANIFEST.MF.

A:

Our pom.xml defines a single class which must contain a public static void main(String[] args) method:

<project xmlns="http://maven.apache.org/POM/4.0.0" ...>
  <modelVersion>4.0.0</modelVersion>
  ...
    <manifestEntries>
       <Main-Class>de.hdm_stuttgart.mi.sd1.App</Main-Class>
    </manifestEntries>
  ...
</project>

The Maven package processing step wraps this class name into the generated first-0.9.jar archive's manifest file META-INF/MANIFEST.MF:

> cat META-INF/MANIFEST.MF 
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven 3.5.2
Built-By: goik
Build-Jdk: 10.0.2
Main-Class: de.hdm_stuttgart.mi.sd1.App

This allows the Java runtime to choose the class to be executed.

Figure 286. Maven javadoc:javadoc Slide presentation
> mvn javadoc:javadoc
[INFO] Scanning for projects...
...
Generating /ma/goik/First/target/site/apidocs/allclasses-noframe.html...
Generating /ma/goik/First/target/site/apidocs/index.html...
Generating /ma/goik/First/target/site/apidocs/overview-summary.html...
Generating /ma/goik/First/target/site/apidocs/help-doc.html...

See e.g. class String documentation.


Figure 287. Maven clean Slide presentation
> mvn clean
...
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ first ---
[INFO] Deleting /ma/goik/first/target
[INFO] ------------------------------------------------------------------------
[