The below rules and steps are mostly automated by simply running the Maven4Migration.java jbang script in the plugin directory.
The rules are quite simple
- the plugin can only depend on
org.apache.maven:maven-api-*
artifacts (no any other maven related artifacts) at compile time - avoid plexus artifacts at compile time
- mojo annotations are now in
org.apache.maven.api.plugin.annotations
package - injection annotations come from
org.apache.maven.api.di
- replace
MavenSession
withorg.apache.maven.api.Session
- replace
MavenProject
withorg.apache.maven.api.Project
- replace classes from
org.apache.maven.model
with their counterparts fromorg.apache.maven.api.model
- unit test needs JUnit 5 and need to use the
org.apache.maven.api.plugin.testing
package
Let's migrate the maven-remote-resources-plugin
.
First create a branch for out work:
git checkout -b migrate-to-maven4
The first things to do are pom changes:
- Maven 4 plugins require JDK 17:
<javaVersion>17</javaVersion>
- and Maven 4
<mavenVersion>4.0.0-rc-2</mavenVersion>
- we need to depend on the new Maven API, so add the following dependencies:
<!-- maven api -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-api-core</artifactId>
<version>${mavenVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-api-model</artifactId>
<version>${mavenVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-api-di</artifactId>
<version>${mavenVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-api-plugin</artifactId>
<version>${mavenVersion}</version>
</dependency>
- replace
org.apache.maven.plugins.annotations.Mojo
withorg.apache.maven.api.plugin.annotations.Mojo
defaultPhase
is now aString
, but constants are available by importingorg.apache.maven.api.Lifecycle
(note that due to lifecycle changes, you may need to use phase qualifiers. For exampleGENERATE_RESOURCES
needs to be replaced withLifecycle.BEFORE + Lifecycle.Phase.RESOURCES
- if your mojo is using
requiresDependencyResolution
orrequiresDependencyCollection
to retrieve artifacts from the executed project, remove add one or more fields annotated withorg.apache.maven.plugins.annotation.Resolution
. In the case ofmaven-remote-resources-plugin
, we have two cases (TODO) - remove
threadSafe
attribute, Maven 4 plugins are required to be thread safe
-
replace
org.apache.maven.plugins.annotations.Parameter
withorg.apache.maven.api.plugin.annotations.Parameter
-
replace
org.apache.maven.plugins.annotations.Component
withorg.apache.maven.api.di.Inject
(though, most components classes/interfaces will have to be replaced) -
it's usually a good idea to replace any injected
File
parameter with aPath
object as they are now supported
If you use Plexus or Sisu to configure your plugin, you need to switch to the Maven DI API.
- replace
javax\.inject\.([A-Z][a-zA-Z]+)
withorg.apache.maven.di.$1
- replace
org\.apache\.maven\.model\.([A-Z][a-zA-Z]+)
withorg.apache.maven.api.model.$1
- replace
org\.apache\.maven\.project\.MavenProject
withorg.apache.maven.api.MavenProject
, and thenMavenProject
withProject
- the
MavenProject
has quite a lot of helper methods to access informations from the model, most of which are not available anymore, so you'll need to go to the model directly usingproject.getModel().getResources()
for example - model objects are now immutable, so if you plugin was creating or modifying model objects, the code will have to be adapted