Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute multiple mojos from one "meta mojo" and parameter sharing

I have created a maven-plugin with some mojos, each has a very special purpose. But for the end user it would be nice to execute some of them at once (the order is crucial).

So how to execute other mojos from a mojos execute? The mojos being executed have some @Parameter fields. So i can't simple new MyMojo().execute.

My 2nd question is: Is there a way to share some @Parameters between Mojos or do i have to declare "@Parameter" in each Mojo that is using them? My idea is to somehow deliver all shared Parameters via utility-class that is providing getters the parameters.

I think the answer to both question somehow lies in understanding the DI-mechanism behind maven-mojos?! I have some experience with Guice but no with Plexus. So could someone please give me some advises?

like image 538
dermoritz Avatar asked Oct 03 '22 13:10

dermoritz


1 Answers

I don't know exactly what your second question means. Maybe they aren't really related. But I try to answer both starting with the first one.

Question 1: How to call a Goal from another Goal?

For this you can use the Apache Maven Invoker.

  1. Add the Maven dependency to your plugin.
    For example:

    <dependency>
        <groupId>org.apache.maven.shared</groupId>
        <artifactId>maven-invoker</artifactId>
        <version>2.2</version>
    </dependency>
    
  2. And then you can call another goal this way:

    // parameters:
    final Properties properties = new Properties();
    properties.setProperty("example.param.one", exampleValueOne);
    
    // prepare the execution:
    final InvocationRequest invocationRequest = new DefaultInvocationRequest();
    invocationRequest.setPomFile(new File(pom)); // pom could be an injected field annotated with '@Parameter(defaultValue = "${basedir}/pom.xml")' if you want to use the same pom for the second goal
    invocationRequest.setGoals(Collections.singletonList("second-plugin:example-goal"));
    invocationRequest.setProperties(properties);
    
    // configure logging:
    final Invoker invoker = new DefaultInvoker();
    invoker.setOutputHandler(new LogOutputHandler(getLog())); // using getLog() here redirects all log output directly to the current console
    
    // execute:
    final InvocationResult invocationResult = invoker.execute(invocationRequest);
    

Question 2: How can I share parameters between mojos?

Did you mean:

  1. How to share parameters between multiple goals inside of one plugin?
    (See "Answer for Question 2.1")
  2. How to reuse parameters of your "meta mojo" for the executed "child mojos"?
    (See "Answer for Question 2.2")

Answer for question 2.1:

You can create a abstract parent class which contains the parameter fields.

Example:

abstract class AbstractMyPluginMojo extends Abstract Mojo {
    @Parameter(required = true)
    private String someParam;

    protected String getSomeParam() {
        return someParam;
    }
}

@Mojo(name = "first-mojo")
public class MyFirstMojo extends AbstractMyPluginMojo {
    public final void execute() {
        getLog().info("someParam: " + getSomeParam());
    }
}

@Mojo(name = "second-mojo")
public class MySecondMojo extends AbstractMyPluginMojo {
    public final void execute() {
        getLog().info("someParam: " + getSomeParam());
    }
}

You can find this technique in almost avery larger maven plugin. For example look at the Apache Maven Plugin sources.

Answer for question 2.2:

You can ind the solution for this already in my answer to question 1. If you want to execute multiple goals inside your "meta mojo" you can just reuse the properties variable.

like image 76
Josef Reichardt Avatar answered Oct 07 '22 20:10

Josef Reichardt