You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by gn...@apache.org on 2022/03/10 07:13:07 UTC

[maven] 06/12: Add the mojo plugin api

This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch mvn4
in repository https://gitbox.apache.org/repos/asf/maven.git

commit 36efde0625e20ad03cb6e61b13be804363bda2a4
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Tue Feb 15 17:10:14 2022 +0100

    Add the mojo plugin api
---
 .../src/main/java/org/apache/maven/api/Event.java  | 21 +++--
 .../java/org/apache/maven/api/MojoExecution.java   | 30 +++++++
 .../java/org/apache/maven/api/plugin/Mojo.java     | 43 ++++++++++
 .../org/apache/maven/api/plugin/MojoException.java | 94 ++++++++++++++++++++++
 .../maven/api/plugin/annotations/Component.java    | 54 +++++++++++++
 .../maven/api/plugin/annotations/Execute.java      | 62 ++++++++++++++
 .../plugin/annotations/InstantiationStrategy.java  | 46 +++++++++++
 .../api/plugin/annotations/LifecyclePhase.java     | 77 ++++++++++++++++++
 .../apache/maven/api/plugin/annotations/Mojo.java  | 89 ++++++++++++++++++++
 .../maven/api/plugin/annotations/Parameter.java    | 92 +++++++++++++++++++++
 .../api/plugin/annotations/ResolutionScope.java    | 76 +++++++++++++++++
 .../maven/impl/DefaultLocalRepositoryManager.java  | 17 ++--
 .../maven/plugin/descriptor/PluginDescriptor.java  | 19 +++--
 13 files changed, 696 insertions(+), 24 deletions(-)

diff --git a/maven-core-api/src/main/java/org/apache/maven/api/Event.java b/maven-core-api/src/main/java/org/apache/maven/api/Event.java
index 9e2c1f6..77c30ae 100644
--- a/maven-core-api/src/main/java/org/apache/maven/api/Event.java
+++ b/maven-core-api/src/main/java/org/apache/maven/api/Event.java
@@ -19,6 +19,10 @@ package org.apache.maven.api;
  * under the License.
  */
 
+import javax.annotation.Nonnull;
+
+import java.util.Optional;
+
 /**
  * Event
  */
@@ -54,6 +58,7 @@ public interface Event
      *
      * @return The type of the event, never {@code null}.
      */
+    @Nonnull
     Type getType();
 
     /**
@@ -61,28 +66,30 @@ public interface Event
      *
      * @return The current session, never {@code null}.
      */
+    @Nonnull
     Session getSession();
 
     /**
      * Gets the current project (if any).
      *
-     * @return The current project or {@code null} if not applicable.
+     * @return The current project or {@code empty()} if not applicable.
      */
-    Project getProject();
+    @Nonnull
+    Optional<Project> getProject();
 
     /**
      * Gets the current mojo execution (if any).
      *
-     * @return The current mojo execution or {@code null} if not applicable.
-     * TODO: return MojoExecution
+     * @return The current mojo execution or {@code empty()} if not applicable.
      */
-    Object getMojoExecution();
+    @Nonnull
+    Optional<MojoExecution> getMojoExecution();
 
     /**
      * Gets the exception that caused the event (if any).
      *
-     * @return The exception or {@code null} if none.
+     * @return The exception or {@code empty()} if none.
      */
-    Exception getException();
+    Optional<Exception> getException();
 
 }
diff --git a/maven-core-api/src/main/java/org/apache/maven/api/MojoExecution.java b/maven-core-api/src/main/java/org/apache/maven/api/MojoExecution.java
new file mode 100644
index 0000000..30574b9
--- /dev/null
+++ b/maven-core-api/src/main/java/org/apache/maven/api/MojoExecution.java
@@ -0,0 +1,30 @@
+package org.apache.maven.api;
+
+/*
+ * 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.
+ */
+
+import javax.annotation.Nonnull;
+
+import org.apache.maven.model.Plugin;
+
+public interface MojoExecution
+{
+    @Nonnull
+    Plugin getPlugin();
+}
diff --git a/maven-core-api/src/main/java/org/apache/maven/api/plugin/Mojo.java b/maven-core-api/src/main/java/org/apache/maven/api/plugin/Mojo.java
new file mode 100644
index 0000000..80819b1
--- /dev/null
+++ b/maven-core-api/src/main/java/org/apache/maven/api/plugin/Mojo.java
@@ -0,0 +1,43 @@
+package org.apache.maven.api.plugin;
+
+/*
+ * 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.
+ */
+
+/**
+ * This interface forms the contract required for <code>Mojos</code> to interact with the <code>Maven</code>
+ * infrastructure.<br>
+ * It features an <code>execute()</code> method, which triggers the Mojo's build-process behavior, and can throw
+ * a MojoExecutionException or MojoFailureException if error conditions occur.<br>
+ * Also included is the <code>setLog(...)</code> method, which simply allows Maven to inject a logging mechanism which
+ * will allow the Mojo to communicate to the outside world through standard Maven channels.
+ */
+@FunctionalInterface
+public interface Mojo
+{
+    /**
+     * Perform whatever build-process behavior this <code>Mojo</code> implements.<br>
+     * This is the main trigger for the <code>Mojo</code> inside the <code>Maven</code> system, and allows
+     * the <code>Mojo</code> to communicate errors.
+     *
+     * @throws MojoException if a problem occurs.
+     */
+    void execute()
+        throws MojoException;
+
+}
diff --git a/maven-core-api/src/main/java/org/apache/maven/api/plugin/MojoException.java b/maven-core-api/src/main/java/org/apache/maven/api/plugin/MojoException.java
new file mode 100644
index 0000000..2d50ca4
--- /dev/null
+++ b/maven-core-api/src/main/java/org/apache/maven/api/plugin/MojoException.java
@@ -0,0 +1,94 @@
+package org.apache.maven.api.plugin;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.api.services.MavenException;
+
+/**
+ * An exception occurring during the execution of a plugin.<br>
+ */
+public class MojoException
+    extends MavenException
+{
+
+    protected Object source;
+
+    protected String longMessage;
+
+    /**
+     * Construct a new <code>MojoExecutionException</code> exception providing the source and a short and long message:
+     * these messages are used to improve the message written at the end of Maven build.
+     */
+    public MojoException( Object source, String shortMessage, String longMessage )
+    {
+        super( shortMessage );
+        this.source = source;
+        this.longMessage = longMessage;
+    }
+
+    /**
+     * Construct a new <code>MojoExecutionException</code> exception wrapping an underlying <code>Exception</code>
+     * and providing a <code>message</code>.
+     */
+    public MojoException( String message, Exception cause )
+    {
+        super( message, cause );
+    }
+
+    /**
+     * Construct a new <code>MojoExecutionException</code> exception wrapping an underlying <code>Throwable</code>
+     * and providing a <code>message</code>.
+     */
+    public MojoException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    /**
+     * Construct a new <code>MojoExecutionException</code> exception providing a <code>message</code>.
+     */
+    public MojoException( String message )
+    {
+        super( message );
+    }
+
+    /**
+     * Constructs a new {@code MojoExecutionException} exception wrapping an underlying {@code Throwable}.
+     *
+     * @param cause the cause which is saved for later retrieval by the {@link #getCause()} method.
+     *              A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.
+     * @since 3.8.3
+     */
+    public MojoException( Throwable cause )
+    {
+        super( cause );
+    }
+
+    public String getLongMessage()
+    {
+        return longMessage;
+    }
+
+    public Object getSource()
+    {
+        return source;
+    }
+
+}
diff --git a/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/Component.java b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/Component.java
new file mode 100644
index 0000000..d5f89ed
--- /dev/null
+++ b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/Component.java
@@ -0,0 +1,54 @@
+package org.apache.maven.api.plugin.annotations;
+
+/*
+ * 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.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Used to configure injection of Plexus components by
+ * <a href="/ref/current/maven-core/apidocs/org/apache/maven/plugin/MavenPluginManager.html">
+ * <code>MavenPluginManager.getConfiguredMojo(...)</code></a>.
+ *
+ * @author Olivier Lamy
+ * @since 3.0
+ */
+@Documented
+@Retention( RetentionPolicy.CLASS )
+@Target( { ElementType.FIELD } )
+@Inherited
+public @interface Component
+{
+    /**
+     * role of the component to inject.
+     * @return the role
+     */
+    Class<?> role() default Object.class;
+
+    /**
+     * hint of the component to inject.
+     * @return the hint
+     */
+    String hint() default "";
+}
diff --git a/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/Execute.java b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/Execute.java
new file mode 100644
index 0000000..81ce2df
--- /dev/null
+++ b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/Execute.java
@@ -0,0 +1,62 @@
+package org.apache.maven.api.plugin.annotations;
+
+/*
+ * 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.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Used if your Mojo needs to fork a <a href="/ref/3.0.4/maven-core/lifecycles.html">lifecycle</a>.
+ *
+ * @author Olivier Lamy
+ * @since 3.0
+ */
+@Documented
+@Retention( RetentionPolicy.CLASS )
+@Target( ElementType.TYPE )
+@Inherited
+public @interface Execute
+{
+    /**
+     * lifecycle phase to fork. Note that specifying a phase overrides specifying a goal.
+     * @return the phase
+     */
+    LifecyclePhase phase() default LifecyclePhase.NONE;
+
+    /**
+     * goal to fork. Note that specifying a phase overrides specifying a goal. The specified <code>goal</code> must be
+     * another goal of the same plugin.
+     * @return the goal
+     */
+    String goal() default "";
+
+    /**
+     * lifecycle id of the lifecycle that defines {@link #phase()}. Only valid in combination with {@link #phase()}. If
+     * not specified, Maven will use the lifecycle of the current build.
+     *
+     * @see <a href="https://maven.apache.org/maven-plugin-api/lifecycle-mappings.html">Lifecycle Mappings</a>
+     * @return the lifecycle id
+     */
+    String lifecycle() default "";
+}
diff --git a/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/InstantiationStrategy.java b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/InstantiationStrategy.java
new file mode 100644
index 0000000..7cac629
--- /dev/null
+++ b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/InstantiationStrategy.java
@@ -0,0 +1,46 @@
+package org.apache.maven.api.plugin.annotations;
+
+/*
+ * 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.
+ */
+
+/**
+ * Component instantiation strategy.
+ *
+ * @author Hervé Boutemy
+ * @since 3.0
+ */
+public enum InstantiationStrategy
+{
+    PER_LOOKUP( "per-lookup" ),
+    SINGLETON( "singleton" ),
+    KEEP_ALIVE( "keep-alive" ),
+    POOLABLE( "poolable" );
+
+    private final String id;
+
+    InstantiationStrategy( String id )
+    {
+        this.id = id;
+    }
+
+    public String id()
+    {
+        return this.id;
+    }
+}
diff --git a/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/LifecyclePhase.java b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/LifecyclePhase.java
new file mode 100644
index 0000000..a2bee4d
--- /dev/null
+++ b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/LifecyclePhase.java
@@ -0,0 +1,77 @@
+package org.apache.maven.api.plugin.annotations;
+
+/*
+ * 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.
+ */
+
+/**
+ * <a href="/ref/3.0.4/maven-core/lifecycles.html">Lifecycle phases</a>.
+ * @author Olivier Lamy
+ * @since 3.0
+ */
+public enum LifecyclePhase
+{
+
+    VALIDATE( "validate" ),
+    INITIALIZE( "initialize" ),
+    GENERATE_SOURCES( "generate-sources" ),
+    PROCESS_SOURCES( "process-sources" ),
+    GENERATE_RESOURCES( "generate-resources" ),
+    PROCESS_RESOURCES( "process-resources" ),
+    COMPILE( "compile" ),
+    PROCESS_CLASSES( "process-classes" ),
+    GENERATE_TEST_SOURCES( "generate-test-sources" ),
+    PROCESS_TEST_SOURCES( "process-test-sources" ),
+    GENERATE_TEST_RESOURCES( "generate-test-resources" ),
+    PROCESS_TEST_RESOURCES( "process-test-resources" ),
+    TEST_COMPILE( "test-compile" ),
+    PROCESS_TEST_CLASSES( "process-test-classes" ),
+    TEST( "test" ),
+    PREPARE_PACKAGE( "prepare-package" ),
+    PACKAGE( "package" ),
+    PRE_INTEGRATION_TEST( "pre-integration-test" ),
+    INTEGRATION_TEST( "integration-test" ),
+    POST_INTEGRATION_TEST( "post-integration-test" ),
+    VERIFY( "verify" ),
+    INSTALL( "install" ),
+    DEPLOY( "deploy" ),
+
+    PRE_CLEAN( "pre-clean" ),
+    CLEAN( "clean" ),
+    POST_CLEAN( "post-clean" ),
+
+    PRE_SITE( "pre-site" ),
+    SITE( "site" ),
+    POST_SITE( "post-site" ),
+    SITE_DEPLOY( "site-deploy" ),
+
+    NONE( "" );
+
+    private final String id;
+
+    LifecyclePhase( String id )
+    {
+        this.id = id;
+    }
+
+    public String id()
+    {
+        return this.id;
+    }
+
+}
diff --git a/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/Mojo.java b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/Mojo.java
new file mode 100644
index 0000000..87eb866
--- /dev/null
+++ b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/Mojo.java
@@ -0,0 +1,89 @@
+package org.apache.maven.api.plugin.annotations;
+
+/*
+ * 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.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation will mark your class as a Mojo (ie. goal in a Maven plugin).
+ *
+ * @author Olivier Lamy
+ * @since 3.0
+ */
+@Documented
+@Retention( RetentionPolicy.CLASS )
+@Target( ElementType.TYPE )
+@Inherited
+public @interface Mojo
+{
+    /**
+     * goal name (required).
+     * @return the goal name
+     */
+    String name();
+
+    /**
+     * default phase to bind your mojo.
+     * @return the default phase
+     */
+    LifecyclePhase defaultPhase() default LifecyclePhase.NONE;
+
+    /**
+     * the required dependency resolution scope.
+     * @return the required dependency resolution scope
+     */
+    ResolutionScope requiresDependencyResolution() default ResolutionScope.NONE;
+
+    /**
+     * the required dependency collection scope.
+     * @return the required dependency collection scope 
+     */
+    ResolutionScope requiresDependencyCollection() default ResolutionScope.NONE;
+
+    /**
+     * does your mojo requires a project to be executed?
+     * @return requires a project
+     */
+    boolean requiresProject() default true;
+
+    /**
+     * if the Mojo uses the Maven project and its child modules.
+     * @return uses the Maven project and its child modules
+     */
+    boolean aggregator() default false;
+
+    /**
+     * does this Mojo need to be online to be executed?
+     * @return need to be online
+     */
+    boolean requiresOnline() default false;
+
+    /**
+     * own configurator class.
+     * @return own configurator class
+     */
+    String configurator() default "";
+
+}
diff --git a/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/Parameter.java b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/Parameter.java
new file mode 100644
index 0000000..6923a95
--- /dev/null
+++ b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/Parameter.java
@@ -0,0 +1,92 @@
+package org.apache.maven.api.plugin.annotations;
+
+/*
+ * 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.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Used to configure your Mojo parameters to be injected by
+ * <a href="/ref/current/maven-core/apidocs/org/apache/maven/plugin/MavenPluginManager.html">
+ * <code>MavenPluginManager.getConfiguredMojo(...)</code></a>.
+ * <p>
+ * Beans injected into Mojo parameters are prepared by <a href="https://www.eclipse.org/sisu/">Sisu</a> JSR330-based
+ * container: this annotation is only effective on fields of the Mojo class itself, nested bean injection
+ * requires Sisu or JSR330 annotations.
+ *
+ * @author Olivier Lamy
+ * @since 3.0
+ */
+@Documented
+@Retention( RetentionPolicy.CLASS )
+@Target( { ElementType.FIELD } )
+@Inherited
+public @interface Parameter
+{
+    /**
+     * name of the bean property used to get/set the field: by default, field name is used.
+     * @return the name of the bean property
+     */
+    String name() default "";
+
+    /**
+     * alias supported to get parameter value.
+     * @return the alias
+     */
+    String alias() default "";
+
+    /**
+     * Property to use to retrieve a value. Can come from <code>-D</code> execution, setting properties or pom
+     * properties.
+     * @return property name
+     */
+    String property() default "";
+
+    /**
+     * parameter default value, may contain <code>${...}</code> expressions which will be interpreted at
+     * inject time: see
+     * <a href="/ref/current/maven-core/apidocs/org/apache/maven/plugin/PluginParameterExpressionEvaluator.html">
+     * PluginParameterExpressionEvaluator</a>. 
+     * @return the default value
+     */
+    String defaultValue() default "";
+
+    /**
+     * is the parameter required?
+     * @return <code>true</code> if the Mojo should fail when the parameter cannot be injected
+     */
+    boolean required() default false;
+
+    /**
+     * Specifies that this parameter cannot be configured directly by the user (as in the case of POM-specified
+     * configuration). This is useful when you want to force the user to use common POM elements rather than plugin
+     * configurations, as in the case where you want to use the artifact's final name as a parameter. In this case, you
+     * want the user to modify <code>&lt;build&gt;&lt;finalName/&gt;&lt;/build&gt;</code> rather than specifying a value
+     * for finalName directly in the plugin configuration section. It is also useful to ensure that - for example - a
+     * List-typed parameter which expects items of type Artifact doesn't get a List full of Strings.
+     * 
+     * @return <code>true</code> if the user should not be allowed to configure the parameter directly
+     */
+    boolean readonly() default false;
+}
diff --git a/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/ResolutionScope.java b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/ResolutionScope.java
new file mode 100644
index 0000000..5fe8862
--- /dev/null
+++ b/maven-core-api/src/main/java/org/apache/maven/api/plugin/annotations/ResolutionScope.java
@@ -0,0 +1,76 @@
+package org.apache.maven.api.plugin.annotations;
+
+/*
+ * 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.
+ */
+
+/**
+ * Dependencies resolution scopes available before
+ * <a href="/ref/current/maven-core/apidocs/org/apache/maven/lifecycle/internal/MojoExecutor.html">mojo execution</a>.
+ *
+ * Important note: The {@code id} values of this enum correspond to constants of
+ * {@code org.apache.maven.artifact.Artifact} class and MUST BE KEPT IN SYNC.
+ *
+ * @author Hervé Boutemy
+ * @since 3.0
+ */
+public enum ResolutionScope
+{
+    /**
+     * empty resolution scope
+     */
+    NONE( null ),
+    /**
+     * <code>compile</code> resolution scope
+     * = <code>compile</code> + <code>system</code> + <code>provided</code> dependencies
+     */
+    COMPILE( "compile" ),
+    /**
+     * <code>compile+runtime</code> resolution scope (Maven 3 only)
+     * = <code>compile</code> + <code>system</code> + <code>provided</code> + <code>runtime</code> dependencies
+     */
+    COMPILE_PLUS_RUNTIME( "compile+runtime" ),
+    /**
+     * <code>runtime</code> resolution scope
+     * = <code>compile</code> + <code>runtime</code> dependencies
+     */
+    RUNTIME( "runtime" ),
+    /**
+     * <code>runtime+system</code> resolution scope (Maven 3 only)
+     * = <code>compile</code> + <code>system</code> + <code>runtime</code> dependencies
+     */
+    RUNTIME_PLUS_SYSTEM( "runtime+system" ),
+    /**
+     * <code>test</code> resolution scope
+     * = <code>compile</code> + <code>system</code> + <code>provided</code> + <code>runtime</code> + <code>test</code>
+     * dependencies
+     */
+    TEST( "test" );
+
+    private final String id;
+
+    ResolutionScope( String id )
+    {
+        this.id = id;
+    }
+
+    public String id()
+    {
+        return this.id;
+    }
+}
diff --git a/maven-core-impl/src/main/java/org/apache/maven/impl/DefaultLocalRepositoryManager.java b/maven-core-impl/src/main/java/org/apache/maven/impl/DefaultLocalRepositoryManager.java
index 41bd191..00ac3dc 100644
--- a/maven-core-impl/src/main/java/org/apache/maven/impl/DefaultLocalRepositoryManager.java
+++ b/maven-core-impl/src/main/java/org/apache/maven/impl/DefaultLocalRepositoryManager.java
@@ -20,7 +20,6 @@ package org.apache.maven.impl;
  */
 
 import java.nio.file.Path;
-import java.nio.file.Paths;
 
 import org.apache.maven.api.Artifact;
 import org.apache.maven.api.LocalRepository;
@@ -37,14 +36,16 @@ public class DefaultLocalRepositoryManager implements LocalRepositoryManager
     public Path getPathForLocalArtifact( Session session, LocalRepository local, Artifact artifact )
     {
         DefaultSession s = (DefaultSession) session;
-        return Paths.get( getManager( s, local ).getPathForLocalArtifact( s.toArtifact( artifact ) ) );
+        String path = getManager( s, local ).getPathForLocalArtifact( s.toArtifact( artifact ) );
+        return local.getPath().resolve( path );
     }
 
     @Override
     public Path getPathForLocalMetadata( Session session, LocalRepository local, Metadata metadata )
     {
         DefaultSession s = (DefaultSession) session;
-        return Paths.get( getManager( s, local ).getPathForLocalMetadata( s.toMetadata( metadata ) ) );
+        String path = getManager( s, local ).getPathForLocalMetadata( s.toMetadata( metadata ) );
+        return local.getPath().resolve( path );
     }
 
     @Override
@@ -52,8 +53,9 @@ public class DefaultLocalRepositoryManager implements LocalRepositoryManager
                                           RemoteRepository remote, Artifact artifact )
     {
         DefaultSession s = (DefaultSession) session;
-        return Paths.get( getManager( s, local ).getPathForRemoteArtifact(
-                s.toArtifact( artifact ), s.toRepository( remote ), null ) );
+        String path = getManager( s, local ).getPathForRemoteArtifact(
+                s.toArtifact( artifact ), s.toRepository( remote ), null );
+        return local.getPath().resolve( path );
     }
 
     @Override
@@ -61,8 +63,9 @@ public class DefaultLocalRepositoryManager implements LocalRepositoryManager
                                           RemoteRepository remote, Metadata metadata )
     {
         DefaultSession s = (DefaultSession) session;
-        return Paths.get( getManager( s, local ).getPathForRemoteMetadata(
-                s.toMetadata( metadata ), s.toRepository( remote ), null ) );
+        String path = getManager( s, local ).getPathForRemoteMetadata(
+                s.toMetadata( metadata ), s.toRepository( remote ), null );
+        return local.getPath().resolve( path );
     }
 
     private org.eclipse.aether.repository.LocalRepositoryManager getManager(
diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java
index 7edcb35..2d4e1ef 100644
--- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java
+++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java
@@ -19,7 +19,8 @@ package org.apache.maven.plugin.descriptor;
  * under the License.
  */
 
-import org.apache.maven.api.Artifact;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.plugin.lifecycle.Lifecycle;
 import org.apache.maven.plugin.lifecycle.LifecycleConfiguration;
@@ -29,19 +30,18 @@ import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
 import org.codehaus.plexus.util.ReaderFactory;
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Reader;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Path;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * @author Jason van Zyl
@@ -259,8 +259,7 @@ public class PluginDescriptor
     {
         if ( artifactMap == null )
         {
-            artifactMap = getArtifacts().stream()
-                    .collect( Collectors.toMap(  a -> a.getGroupId() + ":" + a.getArtifactId(), a -> a ) );
+            artifactMap = ArtifactUtils.artifactMapByVersionlessId( getArtifacts() );
         }
 
         return artifactMap;
@@ -398,17 +397,17 @@ public class PluginDescriptor
     private InputStream getDescriptorStream( String descriptor )
         throws IOException
     {
-        Path pluginFile = ( pluginArtifact != null ) ? pluginArtifact.getPath().orElse( null ) : null;
+        File pluginFile = ( pluginArtifact != null ) ? pluginArtifact.getFile() : null;
         if ( pluginFile == null )
         {
             throw new IllegalStateException( "plugin main artifact has not been resolved for " + getId() );
         }
 
-        if ( Files.isRegularFile( pluginFile ) )
+        if ( pluginFile.isFile() )
         {
             try
             {
-                return new URL( "jar:" + pluginFile.toUri() + "!/" + descriptor ).openStream();
+                return new URL( "jar:" + pluginFile.toURI() + "!/" + descriptor ).openStream();
             }
             catch ( MalformedURLException e )
             {
@@ -417,7 +416,7 @@ public class PluginDescriptor
         }
         else
         {
-            return Files.newInputStream( pluginFile.resolve( descriptor ) );
+            return new FileInputStream( new File( pluginFile, descriptor ) );
         }
     }