Slide 1

Slide 1 text

Wait no more, here comes Maven 4! Robert Scholte & Maarten Mulders

Slide 2

Slide 2 text

Apache Maven History 2004 2005 2024 2010 1.0 (jul. ‘04) 2.0 (oct. ‘05) 1.1 (jun. ‘07) 2.2.1 (nov. ‘09) 3.0 (oct. ‘10) 3.9.9 (aug. ‘24)

Slide 3

Slide 3 text

TL;DR: With Maven 4… …your existing projects should (still) be buildable… …except some warnings you may have ignored about things you’re probably doing wrong… …that will become an error in this major release.

Slide 4

Slide 4 text

Birds’ Eye View of Apache Maven 1. A Java application 2. A plugin execution framework, targeted at building software 3. The “Core” plugins maintained by the Maven team

Slide 5

Slide 5 text

Birds’ Eye View of Apache Maven Input ● command-line arguments: plugin:goal or lifecycle phase + flags ● system properties & environment variables ● pom.xml ● settings.xml Output ● “it depends” (on all the inputs)

Slide 6

Slide 6 text

Command Line Arguments

Slide 7

Slide 7 text

Changes in Command Line Arguments 1. Success/failure conditions 2. Elvis-like operator for profiles and modules 3. Reactor 4. Old & New

Slide 8

Slide 8 text

(1) Fail on Severity Plugin developer: public void execute() throws MojoException { log.error("Not enough coffee"); } [ERROR] Not enough coffee [INFO] ----------------------------------------------------------------------------- [INFO] BUILD SUCCESS [INFO] ----------------------------------------------------------------------------- [INFO] Total time: 2.557 s [INFO] Finished at: 2024-09-20T21:09:38+02:00 [INFO] ----------------------------------------------------------------------------- Maven:

Slide 9

Slide 9 text

(1) Fail on Severity Two motivations: 1. By default, only Exceptions make the build fail → error messages do not! 2. “A warning is a failure in the making” → you want a warningless build. --fail-on-severity

Slide 10

Slide 10 text

(1) Change in checksum verification ● Maven verifies checksums of project dependencies. ● In Maven 2 and 3, if that verification failed, it would be logged as a warning. ● Corrupted artifacts should not, by default, be used for builds. ● Maven 4 will by default fail the build in this case ○ Suppress with -c or --lax-checksums if you really must.

Slide 11

Slide 11 text

(2) Optional Profiles and Modules Using non-existing modules and profiles will fail the build… ● -Pcodecoverage versus -P!codecoverage Unless... ● -P?codecoverage versus -P!?codecoverage The ? prefix means “[de]activate if exists, but don’t fail if it doesn’t” Now logged twice (at start and at end): The requested optional profiles [codecoverage] could not be activated or deactivated because they do not exist.

Slide 12

Slide 12 text

(2) Optional Modules Same as above, but with -pl / --projects :-)

Slide 13

Slide 13 text

(3) The Reactor ● All modules in a multi-module project that will be built. ● Dependencies determine the order in which they will be built. ● Maven 3’s --resume-from reduces the graph too aggressively.

Slide 14

Slide 14 text

(3) Project Root Awareness With Maven 3, the Reactor would 1. apply --resume-from (pruning the project graph) 2. attempt to build remaining modules

Slide 15

Slide 15 text

(3) Project Root Awareness And this is how mvn clean install was born: a work-around for a bug! --resume-from can work* with previous mvn install.

Slide 16

Slide 16 text

(3) Project Root Awareness With Maven 4, the Reactor will 1. remembers the original project structure 2. apply --resume, --resume-from, or --projects 3. build remaining modules with the original project structure in mind

Slide 17

Slide 17 text

Credit where credit is due GitHub - aalmiray/mvn-clean-install: A collection of Maven related memes

Slide 18

Slide 18 text

(4) New kids on the block ● -ps, --project-settings Alternate path for the project settings file

Slide 19

Slide 19 text

(4) “Time to say goodbye” “Ineffective, only kept for backward compatibility” in Maven 3: ● -cpu ● -npr ● -npu ● -up

Slide 20

Slide 20 text

Slide 21

Slide 21 text

The Project Object Model

Slide 22

Slide 22 text

Spot the SPOD Maven 2 and above is based on a Single Point Of Definition: pom.xml The pom.xml loaded during build is EXACTLY the same as the pom.xml that is installed or deployed 📃→📃

Slide 23

Slide 23 text

What’s missing - Encoding (sourceEncoding, resourceEncoding, reportEncoding) * - Global dependency exclusion - Scope import in pluginManagement - Mixin POM fragments - QualityManagement section - Codeformatting section - Advanced control over plugin goal execution order - Separate site distributionManagement for release and snapshot - XML Attribute support - …

Slide 24

Slide 24 text

Workarounds without changing the XSD (1) UTF-8

Slide 25

Slide 25 text

Workarounds without changing the XSD (2) ... * *

Slide 26

Slide 26 text

POM readers It is not just Maven itself - Artifact Repository Managers - Build tools - CI Servers - Dependency Updaters (e.g. Dependabot and Renovate) - Editors and IDEs - Further… POM consumers

Slide 27

Slide 27 text

modelVersion 4.0.0 THE metadata file in Maven Central

Slide 28

Slide 28 text

Build/Consumer POM Separation Build POM: The pom.xml in the source repository / codebase Configuration file for building a project Consumer POM: The pom.xml in the artifact repository Accessible via a Maven Coordinate (groupId:artifactId:version) e.g used as dependency, maven-plugin, maven-extension

Slide 29

Slide 29 text

The new flow of a POM 1 Build POM This is pom .xm l in your codebase 2 Enriched POM (internal) Resolve required elem ents 3 Consum er POM (generated) Reduce to m odelVersion 4.0.0

Slide 30

Slide 30 text

modelVersion redundancy 4.0.0

Slide 31

Slide 31 text

Context for the pom Local System Artifact Repository

Slide 32

Slide 32 text

Context for the pom Local System Artifact Repository 👍 👍

Slide 33

Slide 33 text

Context for the pom Local System Artifact Repository 👍 👍 👍

Slide 34

Slide 34 text

Context for the pom Local System Artifact Repository 👍 😕 👍 👍

Slide 35

Slide 35 text

(Relative) Local System Paths ../pom.xml child1

Slide 36

Slide 36 text

Parent and redundancy Local system Artifact Repository groupId required artifactId version relativePath useless

Slide 37

Slide 37 text

Parent and redundancy Local system Artifact Repository groupId required artifactId version relativePath useful useless

Slide 38

Slide 38 text

Parent and redundancy Local system Artifact Repository groupId resolvable via relativePath* required artifactId version relativePath useful useless [maven-release-plugin] prepare release maven-3.9.9 · apache/maven@8e8579a (github.com)

Slide 39

Slide 39 text

Dependencies and redundancy Local system Artifact Repository groupId required artifactId required version required In case of multimodule dependencies

Slide 40

Slide 40 text

Dependencies and redundancy Local system Artifact Repository groupId required required artifactId required required version required In case of multimodule dependencies

Slide 41

Slide 41 text

Dependencies and redundancy Local system Artifact Repository groupId required required artifactId required required version resolvable via reactor (via modules) required maven/pom.xml at 8e8579a9e76f7d015ee5ec7bfcdc97d260186937 · apache/maven (github.com) In case of multimodule dependencies

Slide 42

Slide 42 text

CI Friendly versions … Externalize value of project version Introduced in Maven 3.5.0 3 placeholders: ${revision} ${sha1} ${changelist}

Slide 43

Slide 43 text

… a half implemented feature … https://repo1.maven.org/…/lib/1.0-cafedead/lib-1.0-cafedead.pom lib 1.0-${sha1} util ${project.version}

Slide 44

Slide 44 text

… for multimodules Requires a (third party) maven-plugin to rewrite the pom.xml 😕

Slide 45

Slide 45 text

The new flow of a POM 1 Build POM This is pom .xm l in your codebase 2 Enriched POM (internal, in m em ory) Add versions: m odelVersion, parent, CI-friendly, reactor dependencies 3 Consum er POM (generated) Rem ove local system entries: relativePath, m odules

Slide 46

Slide 46 text

When everything fails… -Dmaven.buildconsumer=false (default : true)

Slide 47

Slide 47 text

Will a consumer POM only contain dependencies? No, we don’t know what consumers read from the pom.xml When the build/consumer pom separation mechanism fully works, it will open the possibility for such a file (with explicit dependencies)

Slide 48

Slide 48 text

Finally, there’s the modelVersion 4.1.0 /project[@root] /project/subprojects/subproject //execution/priority //extension/configuration //profile/activation/package *

Slide 49

Slide 49 text

The new flow of a POM 1 Build POM This is pom .xm l in your codebase 2 Enriched POM (internal, in m em ory) Add versions: m odelVersion, parent, CI-friendly, reactor dependencies 3 Consum er POM (generated) Rem ove local system entries: relativePath, m odules Rem ove/transform new er m odelVersion features

Slide 50

Slide 50 text

Slide 51

Slide 51 text

For Library Devs

Slide 52

Slide 52 text

Introduce "bom" packaging ● A BOM should only contain the (public) modules of a multi-module project. These are the versions that MUST be in sync within another Maven project. ● "bom" packaging rewrites the dependencyManagement applying the parents version ● Details are at MNG-7879

Slide 53

Slide 53 text

For Maven Plugin Devs

Slide 54

Slide 54 text

For Maven Plugin Devs ● Immutable model ● Maven Bill-of-Materials

Slide 55

Slide 55 text

Other stuff

Slide 56

Slide 56 text

Application Lifecycle Management ❏ Cleanup of dependencies, both on Core and Plugins ❏ Lots of upgrades to external dependencies ❏ Introduction of a few new ones ❏ More fine-grained modularity inside Maven Dependency count Total age Average age 3.9.9 35 24479 days (~ 67 years) 699 days (~ 1,9 years) 4.0.0-beta-4 40 23864 days (~ 65 years) 568 days (~ 1,5 years)

Slide 57

Slide 57 text

New lifecycle phases: pre-* and post-* ● Makes it easier to hook executions into a precise point of the default lifecycles ● Even more fine-grained ordering by using the [xxx] ordering: after:compile[100] after:compile[200]

Slide 58

Slide 58 text

A project-local repository ● Further prevents “polluting” the user repository ○ Unless, of course, you still use mvn install - but you don’t do that anymore, do you? ● Only contains the produced artifacts for that project, not the consumed ones.

Slide 59

Slide 59 text

${pom.*} expressions no longer work ● ${pom.*} expressions were already deprecated in Maven 3 ● You had 10+ years to remove them… Now we “help” you a bit 🦹 ● Simply doesn’t work anymore → it has become a literal value now.

Slide 60

Slide 60 text

Runtime requirement: Java 17 Why? ● Unlocks new language features. ● Require a more secure runtime. Maven 2.0 2005 Java 1.4 Maven 2.2.1 2009 Java 5 Maven 3.0 2010 Java 5 Maven 3.9.9 2024 Java 8 Maven 4.0 ? Java 17

Slide 61

Slide 61 text

Runtime requirement: Java 17 😡 So My Java 8 Project Has To Migrate To Java 17 All Of A Sudden?! 😌 Relax! ● If your runtime supports the desired target, ○ define maven.compiler.source and maven.compiler.target properties as 1.8. ○ define maven.compiler.release property for 11 and up. ● Otherwise, use Toolchains: “A toolchains is a way to specify the path to the JDK to use for all of those plugins in a centralised manner, independent from the one running Maven itself.”

Slide 62

Slide 62 text

Cosmetics: use those (ultra) wide screens! ● Maven 3 was still in 80’s mode and cropped most output at 80 chars per line ● Maven 4 catches up and uses full width or falls back to 130 chars

Slide 63

Slide 63 text

Default plugin versions upgraded ● Super POM (the java.lang.Object of any project) declares default versions for maven-*-plugin ● Subject to change with every release of Maven ● Better explicitly specify the versions you use ● Maven will now issue a warning if you rely on Super POMs values

Slide 64

Slide 64 text

Go Forth and Test 💾 Maven 4.0.0-beta-4 🧪 Try 🛠 Reproduce 📃 Report

Slide 65

Slide 65 text

🙏 Thank you! All demos at https://github.com/mthmulders/maven4-examples/