This week we released Apache Maven 3.3.1 with many new features, but the changes to the core extension loading mechanism is the most significant addition. Why? It allows fairly radical behavioural changes in Maven without having to fork Maven’s core or use custom Maven distributions. A concrete example of this mechanism in action is Polyglot for Maven: with stock Maven 3.3.1 you can dynamically load an extension that can read a POM encoded in a Ruby DSL. Extremely powerful, and entirely transparent to Maven’s core.
The primary driver for this change to the core loading mechanism is work Takari is doing with customers to improve many basic Maven capabilities and develop a Continuous Delivery pipeline. For many of the changes all we require is a new lifecycle and those changes have gone into the Takari Lifecycle, but many other capabilties require deeper integration with Maven. These integrations take the form of Maven extensions and to date we have been using a custom Maven distribution with our new extensions being loaded from ${MAVEN_DIST}/lib/ext
Having custom Maven distributions, or asking users to drop required extensions into their ${MAVEN_HOME}/lib/ext
is problematic for a number of reasons but most of all it’s terribly inconvenient and error prone. All Maven users expect new capabilities in the form of build extensions (like Tycho) and plugins to be downloaded and integrated into Maven while it’s running. Now core extensions can work the same way. As a developer on a project you can simply declare the core extensions you want loaded by enumerating them in a ${maven.multiModuleProjectDirectory}/.mvn/extensions.xml
:
<?xml version="1.0" encoding="UTF-8"?> <extensions> <extension> <groupId>io.takari.polyglot</groupId> <artifactId>polyglot-ruby</artifactId> <version>0.1.5</version> </extension> </extensions>
Here we are telling Maven that we want to use pom.rb
files as the source for the POM. As an aside, the JRuby developers have been using pom.rb
files for quite some time but have been using an inconvenient custom distribution method to date. We hope this new core extension mechanism makes their lives easier.
You might want to try Takari’s Smart Builder and Concurrent Safe Local Repository for faster and safer builds:
<?xml version="1.0" encoding="UTF-8"?> <extensions> <extension> <groupId>io.takari.maven</groupId> <artifactId>takari-smart-builder</artifactId> <version>0.4.0</version> </extension> <extension> <groupId>io.takari.aether</groupId> <artifactId>takari-concurrent-localrepo</artifactId> <version>0.0.7</version> </extension> </extensions>
This will instruct Maven to load and inject alternate implementations of the local repository components and build scheduler.
The important thing to note is that users of your build don’t need to do anything special, or know anything in particular about the extensions you’re using. All normal Maven commands will work as per usual. So even if you’re using some new extensions and are using a custom POM format the standard mvn install
will work.
Currently Takari has a handful of new extensions that will now be easy to use, there are the Polyglot for Maven extensions but most importantly it opens a key pathway to evolve Maven in a sane way. Core extensions can be developed outside of Maven and the ones that are deemed high beneficial and generally applicable can one day be integrated back into Maven itself. We believe that core extensions will be the path to proper consumer POM support (build time vs dependency resolution time) and proper mixin support.
Please join our Maven Dev Hangout if you’re interested in learning more about core extensions and please feel free to ask questions and leave comments!
To use Maven correctly you'll need to understand the fundamentals. This class is designed to deliver just that.