4

I'm creating a Maven archetype, and I'm looking at the source of other archetypes.

I was able to figure out how files and folders are created, and how substitution occurs within files of an archetype.

Now I want to write some code that runs when the archetype runs for a new project, to manipulate the copied files and do some other stuff.

How do I do that ? The guide to making archetypes seems outdated and never mentions that.

Community
  • 1
  • 1
Leonel
  • 28,541
  • 26
  • 76
  • 103

2 Answers2

2

I use property -Dgoal of archetype maven plugin. In this property you can specify additional goals to immediately run on the project created from the archetype.

So, I create a new maven plugin module in my maven archetype project and this module contains all additional java logic that I want to be executed. I need not specify this plugin in newly created pom.xml of the generated project.

More details: here is pom.xml of maven-plugin:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>yourGroupId</groupId>
<artifactId>init-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>   

<dependencies>       
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-plugin-api</artifactId>
        <version>3.0.4</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-project</artifactId>
        <version>3.0-alpha-2</version>
    </dependency>
</dependencies>

And here is the Mojo:

/**
 * @goal maven-plugin-init
 */
public class InitMojo extends AbstractMojo
{    
    /**
     * @parameter expression="${project.basedir}"
     */
    private File basedir;
    public void execute() throws MojoExecutionException, MojoFailureException
    {
       //write initialization logic here
    }
}

So, in the "basedir" will be the basedir of the newly created project.

The only issue is how to pass input parameters of our archetype to our initialization plugin. I just create using archetype a file "initial.properties" in the root of the newly created project and store there all input parameters. And then read this file in initialization plugin.

To launch your archetype use following command: mvn archetype:generate $archetype_properties -Dgoals=yourGroupId:init-maven-plugin:maven-plugin-init

Walery Strauch
  • 6,792
  • 8
  • 50
  • 57
V. Artyukhov
  • 644
  • 10
  • 18
0

V. Artyukhov is right but the things you want to do (modify files etc.) can quite easy be done by using -Dgoals:antrun:run with a pom like below. You don't need your own plugin. Ant makes sense here because you can put many file operations together in one statement. Notice the id default-cli which makes the execution come in when using command-line (as -Dgoals does).

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <id>default-cli</id>
            <configuration>
                <target>
                    <ant antfile="src/ant/custom.xml" inheritRefs="true">
                        <property name="customGroupId" value="${customGroupId}"/>
                        <property name="customArtifactId" value="${customArtifactId}"/>
                        <property name="customVersion" value="${customVersion}"/>
                    </ant>
                </target>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Jan
  • 930
  • 9
  • 25
  • Jan: I tried what you suggested and the plugin is being run when I build the archetype, not when I run archetype:generate. A quick demonstration of that is to use maven-antrun-plugin and echo out some messages. I don't think it's possible to insert any runnable code into an archetype project that will run at archetype:generate. V. Artyukhov's solution seems to be the only way. – Thirlan May 24 '13 at 20:01
  • @Thirlan: Alas you're right - I had the case in mind but it only manipulates something before the install of the archetype in the repository. I updated my answer according to that. – Jan May 31 '13 at 07:46