Apache Maven is 20 years old.
Looking at our detailed releases history:
- Maven 1 had 12 releases from 2002 to 2007,
- Maven 2 had 16 releases from 2005 to 2009,
- Maven 3 had 38 releases from 2009 to now, still counting.
For users, there was a big breaking change from Maven 1 to Maven 2, but since then, compatibility has been kept quite under control: even switching from 2 to 3 was not really a big concern.
But now, we need Maven 5, folks…
What is Maven?
When we switched to Git, we ended up with nearly 100 Git repositories: the Maven binary distribution that you download and install on your computer is just one of these.
In fact, Maven is a plugins execution environment, which requires base plugins and many internal components.
Maven provides near 50 “built-in” plugins, split in four different categories:
- core plugins, like clean, compiler, install, deploy, site, surefire (test), …
- packaging plugins, like jar, war, shade, source, jlink, jmod, …
- reporting plugins, like javadoc, jxr, checkstyle, pmd, jdeps, …
- and many tools plugins, like archetype, assembly, enforcer, dependency, release, antrun, scripting, …
And there are many shared components, Doxia for site rendering with skins, archetypes, indexer, Modello, Classworlds.
You can find a full map on our “Get Sources” page:
Of course, 50 plugins is only the “built-in” plugins, maintained by the Maven team at Apache: one key asset of Maven is also the huge ecosystem of third-party plugins maintained by a large community. Currently, searching on Maven’s Central Repository, we find 5,817 OSS Maven plugins: it’s more than 100 community Maven plugins for one “built-in”.
And in addition to that huge code base, there is also the Maven Central repository: it’s not about code, it’s about services to publish artifacts and download them.
Maven team publish nearly 500 GA=GroupId:ArtifactId (with groupId starting with org.apache.maven) to the Maven Central repository, while Apache Software Foundation publish nearly 25,000 GA (org.apache.* = 50 * org.apache.maven.*). Moreover, the whole community publish nearly 450,000 GA (900 times as much as Maven), eventually not even building with Maven, or not written in Java.
In 20 years, the Maven Central Repository has become a critical service provided to the whole JVM ecosystem, whatever the build tool or the language is.
Why Moving Away from Maven 3?
As we said before, we kept pretty good compatibility over time, then we only needed minor versions to describe updates on each release. Even the switch from Maven 2 to 3 could have been seen as a minor release, from a user point of view: but internals had really changed a lot, so we decided it deserved a major version bump.
One key thing did not change for Maven 2 and 3: we’re still at POM v4, which was defined in 2005 for Maven 2.0.
It’s not that this schema is perfect. We found many shortcomings that we managed to fix without changing the POM v4 schema, introducing:
- “
import
” scope in dependencyManagement, to permit importing a BOM POM, - transitive dependencies excludes, by supporting “
*
” wildcard as exclude value, - build time vs runtime prerequisites, clarifying that POM prerequisite is runtime, while build time prerequisites are to be defines with Enforcer plugin,
- properties looking like new POM elements to add new important conventions:
${project.build.sourceEncoding}
for explicit source encoding configuration,${project.reporting.outputEncoding}
for reporting output encoding configuration,${project.build.outputTimestamp}
for Reproducible Builds,
- a few attributes to be able to fine tune inheritance.
But such changes were limited in scope, hard to do, and caused some compatibility issues with the full ecosystem: not only older Maven versions consuming such enhanced POM files from their dependencies, but also IDE or CI integrations, or even other build tools that were consuming dependencies from Maven Central Repository.
The fact is: POM v4 is used in the Maven Central Repository as a cornerstone for dependency management in the entire JVM ecosystem, whatever the language or build tool is used. Then POM v4 needs to remain as-is, preserved in amber.
With the Maven build schema preserved in amber, we can’t evolve much: we’ll stay forever with Maven 3 minor releases, unable to implement improvements that we imagine will require seriously updating the POM schema…
Introducing Maven 5
Maven is the only build tool affected by this issue: every other build tool has its own build schema that can evolve over time, and generates a POM for their consumers when deploying built artifacts to Maven Central.
We came to the conclusion that this is what Maven needs to do: have a new POM v5 schema that has new elements and features for build time. And when deploying to Maven Central, generate a good old POM v4 that will be used by consumers downloading and using the pre-built artifacts.
In summary, we need to make a distinction between two POM types:
- the build POM, stored in the project source control, that uses v5 schema for build time, requiring a new Maven version able to use the new features associated to the new schema,
- the consumer POM, that is published to Maven Central in the good old v4 schema, so every past or future build tool can continue to consume pre-built artifacts as usual for their dependencies.
Of course, POM v5 requires to be the build schema for Maven 5, doesn’t it?
What about Maven 4?
This leaves us with a gap between Maven 3 and 5: is there something useful to do in between?
Yes, of course!
What if we introduced build/consumer POM separation that is required for Maven 5, keeping POM v4 as a build schema, but improving user experience? This way we can build up experience and see if everything works as expected.
We found a few really useful cases:
- automatic parent versioning (in build POM):
Parent POM version in pom.xml is useful in the Maven Central repository, but on local disk where usually parent pom.xml is available at “..
”, it just creates duplicate info that needs to be updated during release, creating a big multi-file commit for a basic version change. Build POM needs a version only at the root pom.xml, which will make life easier, while consumer POM in Maven Central will keep explicit versions for compatibility,
- automatic reactor versioning (in build POM):
Same as the current version of every module in a build, internal dependencies share naturally the same version. We can have implicit versions in build POM, with usual explicit versions automatically injected in consumer POM in Maven Central,
- CI-friendly placeholders replacement (in consumer POM):
Have you ever used CI-friendly${sha1}
,${revision}
or${changelist}
in your pom.xml version? While having the placeholder in your build pom.xml and in SCM, once deployed to Maven Central, it’s better to know which value was defined during build, isn’t it?
- relative path from parent removal (in consumer POM):
The path to parent POM is useful when building, to refer to local disk location. But once the consumer POM is published to Maven Central, this local disk reference does not make sense any more: removing the value will just make it clear.
But it’s just Maven 4 features related to this build vs consumer POM. We also have other nice enhancements already done that will be covered in detail when we release.
When will Maven 4 be Available?
The usual next question is: when will it be released?
We are near doing Maven 4.0.0-alpha-1, with 229 issues already done and just 11 remaining.
How much time will be necessary? It all depends on time contributors will find to work on it, reproduce issues, then find how to fix them. This is where the community can help: we need people who will focus on precise issues, contact us on the developer mailing list, and take time to dig into it and persevere with the team.
And of course, contributing to Maven 4, what we also call “Maven Core”, is not the only project where you can help us: you can do it also for plugins or any other component, which are generally a much easier target.
While at it, contributing to documentation is easy: just use the edit button to create your PR
Done, you’re a proven Maven code contributor.
Author: Hervé Boutemy
Apache Maven PMC
Member of the Apache Software Foundation