Some notes by me while taking this course.
verify
to build the project
settings.xml
.
Noticed that when running some maven tasks for the first time (like clean
and package
) it downloads artifacts and it takes a lot of time, and the next executions go really fast (no need to download stuff).
Doing this in a pipeline, where the runner is a “fresh” container, results in downloading artifacts allways.
There must be a way to prevent this.
UPDATE: yes, and it’s by using the cache feature of the CI tool (like GitLab CI). Caching dependencies is the way to go.
The very first execution of mvn package
for my simple Hello World project took 01:08 min, because maven needed to download a bunch of artifacts from https://repo.maven.apache.org/
.
The next executions took less than 1 second!!!
That fact alerted me that probably I could dramatically improve the speed of my GitLab CI pipeline…
Every stage of the pipeline starts a “fresh” container. We have two stages with maven (one to build and another to run a SAST Scanner), I noticed that in both we’re downloading artifacts…
I need to save such artifacts in a cache!
This “Hello World”:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
$ # the source is compiled with `javac`
$ javac HelloWorld.java
$ # it creates the .class file
$ ls
HelloWorld.class HelloWorld.java
$ # you can run that class with the `java` command:
$ java HelloWorld
Hello World!
$ # let's build a .jar file with the `jar` command
$ jar cf myjar.jar HelloWorld.class
$ # let's run the class HelloWorld from that .jar file
$ java -classpath myjar.jar HelloWorld
Hello World!
Note: the .jar
file is actually a zipped file.
In simple terms, what Maven basically does is compiling classes and then package them into a .jar
file.
Note: there’s a commons-lang3-3.8.1.jar
file in the zipped “Resources” of the lecture.
# building it
$ javac -classpath ./lib/* HelloWorld.java
# running it
$ java -classpath ./lib/*:./ HelloWorld
Hello World!
Hello world
Another thing maven does is managing such dependencies.
In order to build with Maven we need a pom.xml
.
Example for our HelloWorld:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>guru.springframework</groupId>
<artifactId>hello-world</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
</project>
Pay attention to that <artifactId>
and <version>
. They’re goint to be used to generate the .jar
file.
# clean out the environment (looks similar to `make clean`)
mvn clean
# create a jar file
mvn package
# inside the `target/` folder you'll see a file named
# `hello-world-0.0.1-SNAPSHOT.jar`
# if you run the `clean` again, the target/ directory will be deleted
mvn clean
# put your HelloWorld.java in a subdir
mkdir -p src/main/java
mv HelloWorld.java src/main/java
# you can clean and package in the same command line
mvn clean package
In order to add dependencies to your project, just add the dependency’s coordinates to your pom.xml
, like this:
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
</dependencies>
In the next run of mvn package
it’ll download the dependencies.
<groupId>guru.springframework</groupId>
<artifactId>hello-world</artifactId>
<version>0.0.1-SNAPSHOT</version>
SNAPSHOT
sufix tells maven this is a development version.Types:
~/.m2/
,-> Central
Project <-> ~/.m2/ <-{
'-> Others
Maven Wagon is a unified Maven API working as a transport abstraction for artifact and repository handling code.
In some corporate environments you may need to configure Wagon for Proxy Settings.
mvn help:effective-pom
Dependency is an artifact which your Maven project depends upon. Typically a jar or pom.
Maven does dependency management.
Dependency Mediation: determines what version to use when multiple versions of the same dependency are encountered. Usually the latest wins.
Dependency Scope:
Dependencies are managed by the Maven Dependency Plugin
Important Goals:
dependency:tree
- shows the dependency tree. Useful for resolving conflicts.dependency:go-offline
- resolve all, prepare to go offline.dependency:purge-local-repository
- clear artifacts from local repository.dependency:sources
- get sources for all dependencies.Note about mvn
syntax: the notation mvn dependency:tree
is like mvn ${plugin}:${goal}
.
https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
Basically: src/main/java
.
Lifecycles and phases provide the framework to call plugin goals in a sequence.
clean
, default
, site
.clean
:
default
:
site
:
Maven Clean Lifecycle
Default Lifecycle - High Level
Key concept:
clean
, default
, site
.It’s wrapper around maven which allows you to build your project via shell script on a machine without Maven installed.
mvn -N io.takari:maven:wrapper
# specify the maven version:
mvn -N io.takari:maven:wrapper -Dmaven=3.6.0
It creates a hidden folder called .mvn/
.
Note: using a wrapper is considered a “best practice”.
Maven Archetypes are project templates.
http://maven.apache.org/archetype/index.html
Example of use:
# from: http://maven.apache.org/archetypes/maven-archetype-simple/
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-simple -DarchetypeVersion=1.4
clean
target/
directory and submodule root folderscompiler:compile
compiler:testCompile
javax.tools.JavaCompiler
resources:resources
resources:testResources
resources:copy-resources
surefire:test
**/Test*.java
**/*Test.java
**/*Tests.java
**/*TestCase.java
jar:jar
jar:test-jar
deploy:deploy
deploy:deploy-file
site:site
site:deploy
site:run
site:stage
site:stage-deploy
site:attach-descriptor
site:jar
site:effective-site