| ~~ Licensed to the Apache Software Foundation (ASF) under one |
| ~~ or more contributor license agreements. See the NOTICE file |
| ~~ distributed with this work for additional information |
| ~~ regarding copyright ownership. The ASF licenses this file |
| ~~ to you under the Apache License, Version 2.0 (the |
| ~~ "License"); you may not use this file except in compliance |
| ~~ with the License. You may obtain a copy of the License at |
| ~~ |
| ~~ http://www.apache.org/licenses/LICENSE-2.0 |
| ~~ |
| ~~ Unless required by applicable law or agreed to in writing, |
| ~~ software distributed under the License is distributed on an |
| ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| ~~ KIND, either express or implied. See the License for the |
| ~~ specific language governing permissions and limitations |
| ~~ under the License. |
| |
| ----- |
| Introduction |
| ----- |
| Hervé Boutemy |
| ----- |
| 2018-07-22 |
| ----- |
| |
| Maven Core Extension Demo Study |
| |
| Demo of Maven Core Extensions: |
| |
| * classical types of core extensions, |
| |
| * how to write them, |
| |
| * how to configure them into your builds. |
| |
| [] |
| |
| * Demo Content |
| |
| {{{./xref/}Code provided here}} demoes one specific type of extension: {{{/examples/maven-3-lifecycle-extensions.html}Maven 3 lifecycle extension}}, and |
| the different results obtained when injecting this extension in the different ways available. |
| |
| Maven lifecycle participation can be provided through 3 APIs: |
| |
| [[1]] {{{/ref/current/maven-core/apidocs/org/apache/maven/execution/AbstractExecutionListener.html}<<<org.apache.maven.execution.AbstractExecutionListener>>>}} object, |
| instantiated and added to listeners like {{{/ref/current/maven-embedder/xref/org/apache/maven/cli/MavenCli.html#L1446}Maven CLI does}} using |
| internal {{{/ref/current/maven-core/apidocs/org/apache/maven/eventspy/internal/EventSpyDispatcher.html}<<<eventSpyDispatcher.chainListener(executionListener)>>> API}} |
| ({{{https://maven.apache.org/ref/current/maven-core/xref/org/apache/maven/eventspy/internal/EventSpyDispatcher.html}source}}) or copying the small implementation, |
| |
| [[2]] {{{/ref/current/maven-core/apidocs/org/apache/maven/AbstractMavenLifecycleParticipant.html}<<<org.apache.maven.AbstractMavenLifecycleParticipant>>>}} Plexus/Sisu/JSR-330 component, |
| |
| [[3]] {{{/ref/current/maven-core/apidocs/org/apache/maven/eventspy/AbstractEventSpy.html}<<<org.apache.maven.eventspy.AbstractEventSpy>>>}} Plexus/Sisu/JSR-330 component. |
| |
| [] |
| |
| This study implements each API (see {{{./apidocs/}javadoc}}) then tests implementations in ITs that configure the extension in different ways: |
| verification done after IT execution checks expected differences (see {{{./invoker-report.html}ITs results}}). |
| |
| * Classical Types of Core Extensions |
| |
| A Maven core extension is a library that goes into |
| {{{/guides/mini/guide-maven-classloading.html#Core_Classloader}Maven Core classloader}}, then is really in the core execution of Maven, unlike |
| a plugin that runs in a child classloader separated from other plugins. |
| |
| There are multiple reasons one wants to put his code in Maven Core classloader: |
| |
| * {{{/guides/mini/guide-using-extensions.html}add a Wagon protocol}}, |
| |
| * override a component of Maven core, to change its behaviour (expertise required...), |
| |
| * inject a {{{/examples/maven-3-lifecycle-extensions.html}lifecycle participant}}. |
| |
| [] |
| |
| * Configuring Maven Core Extensions |
| |
| There are multiple methods available to declare a library as an extension: |
| |
| [[1]] classical POM's {{{/ref/current/maven-model/maven.html#class_build}<<<project.build.extensions.extension>>>}} (since Maven 2), |
| |
| [[2]] put jars in Maven <<<$\{maven.home\}/lib>>> (since Maven 2) or <<<$\{maven.home\}/lib/ext>>> (since Maven 3), |
| |
| [[3]] use <<<-Dmaven.ext.class.path=[path to files]>>> (since Maven 3.0.2, |
| see {{{https://issues.apache.org/jira/browse/MNG-4936}MNG-4936}}), |
| |
| [[4]] configure in {{{/ref/current/maven-embedder/core-extensions.html}<<<.mvn/extensions.xml>>>}} (since Maven 3.3.1) |
| |
| [] |
| |
| Declaring an extension in POM is the most classical and flexible way to do: the only drawback is that the extension |
| is activated after POM reading, which can be too late for some very specific use cases like |
| {{{/ref/current/maven-core/apidocs/org/apache/maven/eventspy/package-summary.html}EventSpy}}. |
| |
| Installing an extension directly inside Maven installation avoids the previous limitation, but is not flexible. |
| |
| <<<-Dmaven.ext.class.path=[path to files]>>> is a little bit more flexible, but remains not configured into |
| the build, which is not suitable to ensure an extension is available at build time. |
| |
| <<<.mvn/extensions.xml>>> is the ultimate solution for these use cases. Its only drawback is that it has been |
| added only in Maven 3.3.1. |
| |
| |
| * References |
| |
| * {{{/guides/mini/guide-maven-classloading.html} Guide to Maven Classloading}} |
| |
| * {{{/examples/maven-3-lifecycle-extensions.html} Example: Using Maven 3 lifecycle extension}} |
| |
| * {{{/guides/mini/guide-using-extensions.html} Guide: Using Extensions}} |