1

We have a custom maven plugin which generates some code artifacts for our project. The plugin has configured the lifecycle like this, with the 'generate-resources' phase calling our custom class.

<?xml version="1.0" encoding="UTF-8"?>
<component-set>
    <components>
        <component>
            <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
            <role-hint>zip</role-hint>
            <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
            <configuration>
                <phases>
                    <generate-resources>com.b.e:productconfig-maven-plugin:generate</generate-resources>
                    <package>com.b.e:productconfig-maven-plugin:zip</package>
                    <install>org.apache.maven.plugins:maven-install-plugin:install</install>
                    <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
                </phases>
            </configuration>
        </component>
    </components>
</component-set>

We've a new requirement to run this 'generate-resources' phase with slightly different parameters. I had hoped we could define a second phase and passing in the mojo custom properties like this

<?xml version="1.0" encoding="UTF-8"?>
<component-set>
    <components>
        <component>
            <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
            <role-hint>zip</role-hint>
            <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
            <configuration>
                <phases>
                    <generate-resources>com.b.e:productconfig-maven-plugin:generate -Dmojo.param=A</generate-resources>
                    <generate-resources>com.b.e:productconfig-maven-plugin:generate -Dmojo.param=B</generate-resources>
                    <package>com.b.e:productconfig-maven-plugin:zip</package>
                    <install>org.apache.maven.plugins:maven-install-plugin:install</install>
                    <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
                </phases>
            </configuration>
        </component>
    </components>
</component-set>

but this throws this error.

[ERROR] Could not find goal 'generate -Dmojo.param=A' in plugin com.b.e:productconfig-maven-plugin:1.0.6-SNAPSHOT among available goals generate, zip -> [Help 1]
org.apache.maven.plugin.MojoNotFoundException: Could not find goal 'generate -DoutputFileBaseDir=/home/poc/b/product_configuration/productconfig-maven-plugin/target/generated/delta' in plugin com.b.e:productconfig-maven-plugin:1.0.6-SNAPSHOT among available goals export, generate
    at org.apache.maven.plugin.internal.DefaultMavenPluginManager.getMojoDescriptor(DefaultMavenPluginManager.java:267)
    at org.apache.maven.plugin.DefaultBuildPluginManager.getMojoDescriptor(DefaultBuildPluginManager.java:185)
    at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.setupMojoExecution(DefaultLifecycleExecutionPlanCalculator.java:152)
    at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.setupMojoExecutions(DefaultLifecycleExecutionPlanCalculator.java:139)
    at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.calculateExecutionPlan(DefaultLifecycleExecutionPlanCalculator.java:116)
    at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.calculateExecutionPlan(DefaultLifecycleExecutionPlanCalculator.java:129)
    at org.apache.maven.lifecycle.internal.BuilderCommon.resolveBuildPlan(BuilderCommon.java:92)

Does anybody know a way to correctly pass parameters into a lifecycle phase?

emeraldjava
  • 10,894
  • 26
  • 97
  • 170

2 Answers2

2

There are two questions with basically the same requirement, none of them with an answer:

I'm pretty sure that this "lifecycle mapping with property/parameter definition" is not going to work.

The declarations in component.xml specify which goal is bound to a certain phase of a lifecycle, a.k.a. lifecycle mapping. In other words and in my understanding:

  • It's about what is executed if a phase is passed during a build run.
  • It's not about how this is done.

None of the references:

mentions:

  1. Binding more than one goal to a phase.

    Since DefaultLifecycleMapping.getPhases(...) returns a Map where the key denotes the phase this isn't possible at all.

  2. A goal-to-phase binding with a property/parameter definition.

    The part Could not find goal 'generate -Dmojo.param=A' of your error message tells me that the complete string of the goal part is considered as goal name, with no further argument extraction applied.

Community
  • 1
  • 1
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
1
  1. For Binding more than one goal to a phase:

    You can just place a comma between the goals, this certainly works on Maven 3.6.1, but I can't say if this is a new feature. i.e.:

    <package>org.apache.maven.plugins:maven-jar-plugin:jar,org.expath.pkg:expath-pkg-maven-plugin:pkg</package>
    
  2. For A goal-to-phase binding with a property/parameter definition:

    I was able to do what you are asking programatically.

    For my plugin, I wanted the ability to optionally have Java classes first compiled and placed in a Jar, but the ultimate package format be a Xar, think of it as a wrapper, which would contain the Jar alongside other things.

    Instead of using the DefaultLifecycleMapping in components.xml, I created my own LifecycleMapping component which specifies the default lifecycle, and from there I was able to set the configuration of (for my use-case) the Jar plugin.

    My custom lifecycle component:

    @Component(role = LifecycleMapping.class, hint = "xar", description = "EXPath Pkg Lifecycle Mapping")
    public class PkgLifecycleMapping implements LifecycleMapping {
    
        private final Map<String, Lifecycle> lifecycleMap = new HashMap<>();
    
        public PkgLifecycleMapping() {
            final Map<String, LifecyclePhase> phases = new HashMap<>();
            phases.put("process-resources", new LifecyclePhase("org.apache.maven.plugins:maven-resources-plugin:resources"));
            phases.put("compile", new LifecyclePhase("org.apache.maven.plugins:maven-compiler-plugin:compile"));
    
            final LifecyclePhase packageLifecyclePhase = new LifecyclePhase("org.apache.maven.plugins:maven-jar-plugin:jar,org.expath.pkg:expath-pkg-maven-plugin:pkg");
    
            // configure the maven-jar-plugin mojo
            final LifecycleMojo jarLifecyclePhase = packageLifecyclePhase.getMojos().get(0);
            Xpp3Dom config = jarLifecyclePhase.getConfiguration();
            if (config == null) {
                config =  new Xpp3Dom("configuration");
            }
            final Xpp3Dom skipIfEmpty = new Xpp3Dom("skipIfEmpty");
            skipIfEmpty.setValue("true");
            config.addChild(skipIfEmpty);
            jarLifecyclePhase.setConfiguration(config);
    
            phases.put("package", packageLifecyclePhase);
    
            phases.put("install", new LifecyclePhase("org.apache.maven.plugins:maven-install-plugin:install"));
            phases.put("deploy", new LifecyclePhase("org.apache.maven.plugins:maven-deploy-plugin:deploy"));
    
            final Lifecycle lifecycle = new Lifecycle();
            lifecycle.setId("default");
            lifecycle.setLifecyclePhases( phases );
    
            lifecycleMap.put("default", lifecycle );
        }
    
        @Override
        public Map<String, Lifecycle> getLifecycles() {
            return lifecycleMap;
        }
    
        @Override
        @Deprecated
        public List<String> getOptionalMojos(final String lifecycle) {
            return null;
        }
    
        @Override
        @Deprecated
        public Map<String, String> getPhases(final String lifecycle) {
            final Lifecycle lifecycleMapping = lifecycleMap.get(lifecycle);
            if (lifecycleMapping != null) {
                return LifecyclePhase.toLegacyMap(lifecycleMapping.getLifecyclePhases());
            } else {
                return null;
            }
        }
    }
    

    You will also need to add the plexus metadata plugin to your build plugins in your pom.xml:

        <plugin>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-component-metadata</artifactId>
            <version>2.0.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate-metadata</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    

    My src/main/resources/META-INF/plexus/components.xml looks like:

    <component-set>
        <components>
            <component>
                <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
                <role-hint>xar</role-hint>
    <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
                <configuration>
                    <type>xar</type>
                    <extension>xar</extension>
                    <packaging>xar</packaging>
                </configuration>
            </component>
        </components>
    </component-set>
    

    After the build my generated target/classes/META-INF/plexus/components.xml looks like:

    <component-set>
        <components>
            <component>
                <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
                <role-hint>xar</role-hint>
                <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
                <configuration>
                    <type>xar</type>
                    <extension>xar</extension>
                    <packaging>xar</packaging>
                </configuration>
            </component>
            <component>
              <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
              <role-hint>xar</role-hint>
              <implementation>org.expath.pkg.maven.PkgLifecycleMapping</implementation>
              <description>EXPath Pkg Lifecycle Mapping</description>
              <isolated-realm>false</isolated-realm>
            </component>
        </components>
    </component-set>
    
adamretter
  • 3,885
  • 2
  • 23
  • 43