如何正确创建maven插件?

How to create a maven plugin properly?

我正在开发一个简单的插件maven示例如下

pom.xml 文件插件:

<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>sample.plugin</groupId>
    <artifactId>hello-maven-plugin</artifactId>
    <version>1.1.1</version>
    <packaging>maven-plugin</packaging>

    <name>hello-maven-plugin Maven Plugin</name>

    <!-- FIXME change it to the project's website -->
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>3.2</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-utils</artifactId>
            <version>3.0.8</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-plugin-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <goalPrefix>hello-maven-plugin</goalPrefix>
                    <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
                </configuration>
                <executions>
                    <execution>
                        <id>default-descriptor</id>
                        <goals>
                            <goal>descriptor</goal>
                        </goals>
                        <phase>process-classes</phase>
                    </execution>
                    <execution>
                        <id>help-descriptor</id>
                        <goals>
                            <goal>helpmojo</goal>
                        </goals>
                        <phase>process-classes</phase>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>

        <pluginManagement>
            <plugins>
                <!--This plugin's configuration is used to store Eclipse m2e settings 
                    only. It has no influence on the Maven build itself. -->
                <plugin>
                    <groupId>org.eclipse.m2e</groupId>
                    <artifactId>lifecycle-mapping</artifactId>
                    <version>1.0.0</version>
                    <configuration>
                        <lifecycleMappingMetadata>
                            <pluginExecutions>
                                <pluginExecution>
                                    <pluginExecutionFilter>
                                        <groupId>
                                            org.apache.maven.plugins
                                        </groupId>
                                        <artifactId>
                                            maven-plugin-plugin
                                        </artifactId>
                                        <versionRange>
                                            [3.2,)
                                        </versionRange>
                                        <goals>
                                            <goal>helpmojo</goal>
                                            <goal>descriptor</goal>
                                        </goals>
                                    </pluginExecutionFilter>
                                    <action>
                                        <ignore></ignore>
                                    </action>
                                </pluginExecution>
                            </pluginExecutions>
                        </lifecycleMappingMetadata>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <profiles>
        <profile>
            <id>run-its</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-invoker-plugin</artifactId>
                        <version>1.7</version>
                        <configuration>
                            <debug>true</debug>
                            <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
                            <pomIncludes>
                                <pomInclude>*/pom.xml</pomInclude>
                            </pomIncludes>
                            <postBuildHookScript>verify</postBuildHookScript>
                            <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
                            <settingsFile>src/it/settings.xml</settingsFile>
                            <goals>
                                <goal>clean</goal>
                                <goal>test-compile</goal>
                            </goals>
                        </configuration>
                        <executions>
                            <execution>
                                <id>integration-test</id>
                                <goals>
                                    <goal>install</goal>
                                    <goal>integration-test</goal>
                                    <goal>verify</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

</project>

代码插件:

package sample.plugin;

/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed 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.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;

import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Goal which touches a timestamp file.
 *
 *
 */
@Mojo( name = "touch", defaultPhase = LifecyclePhase.PROCESS_SOURCES )
public class MyMojo
    extends AbstractMojo
{
    /**
     * Location of the file.
     */
    @Parameter( defaultValue = "${project.build.directory}", property = "outputDir", required = true )
    private File outputDirectory;

    public void execute()
        throws MojoExecutionException
    {
        getLog().info("Mensagem de Log - Ricardo!!!");
        File f = outputDirectory;

        if ( !f.exists() )
        {
            f.mkdirs();
        }

        File touch = new File( f, "touch.txt" );

        FileWriter w = null;
        try
        {
            w = new FileWriter( touch );

            w.write( "touch.txt" );
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Error creating file " + touch, e );
        }
        finally
        {
            if ( w != null )
            {
                try
                {
                    w.close();
                }
                catch ( IOException e )
                {
                    // ignore
                }
            }
        }
    }
}

pom.xml使用插件的项目文件:

<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>exemplo.utilizacao.plugin.maven</groupId>
  <artifactId>teste</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>teste</name>
  <description>teste</description>
  <dependencies>  
        <dependency>   
            <groupId>org.apache.maven</groupId>   
            <artifactId>maven-plugin-api</artifactId>   
            <version>2.0</version>  
        </dependency>   
    </dependencies>  
    <build>  
        <plugins>  
            <plugin>  
                <groupId>sample.plugin</groupId>  
                <artifactId>maven-plugin-plugin</artifactId>  
                <version>1.0-SNAPSHOT</version>  
                <executions>  
                    <execution>  
                    <phase>compile</phase>  
                    <goals>  
                        <goal>sayhi</goal>  
                    </goals>  
                    </execution>  
                </executions>  
            </plugin>  
        </plugins>
        <pluginManagement>
            <plugins>
                <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
                <plugin>
                    <groupId>org.eclipse.m2e</groupId>
                    <artifactId>lifecycle-mapping</artifactId>
                    <version>1.0.0</version>
                    <configuration>
                        <lifecycleMappingMetadata>
                            <pluginExecutions>
                                <pluginExecution>
                                    <pluginExecutionFilter>
                                        <groupId>sample.plugin</groupId>
                                        <artifactId>
                                            maven-plugin-plugin
                                        </artifactId>
                                        <versionRange>
                                            [1.0-SNAPSHOT,)
                                        </versionRange>
                                        <goals>
                                            <goal>sayhi</goal>
                                        </goals>
                                    </pluginExecutionFilter>
                                    <action>
                                        <ignore></ignore>
                                    </action>
                                </pluginExecution>
                            </pluginExecutions>
                        </lifecycleMappingMetadata>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>  
</project>

当 运行 在使用插件的项目中通过 ecplise 安装 mvn 时,我收到以下消息:

[INFO] Scanning for projects...
[INFO] 
[INFO] Using the builder org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder with a thread count of 1
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building teste 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for sample.plugin:maven-plugin-plugin:jar:1.0-SNAPSHOT is missing, no dependency information available
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.436 s
[INFO] Finished at: 2015-08-26T10:11:45-03:00
[INFO] Final Memory: 4M/88M
[INFO] ------------------------------------------------------------------------
[ERROR] Plugin sample.plugin:maven-plugin-plugin:1.0-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact sample.plugin:maven-plugin-plugin:jar:1.0-SNAPSHOT -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginResolutionException

如何正确使用我创建的 maven 插件?我确定还从两个项目中正确创建了 pom.xml 文件。我哪里错了?

你的插件依赖不正确:

<plugin>
    <groupId>sample.plugin</groupId>
    <artifactId>maven-plugin-plugin</artifactId>
    <version>1.0-SNAPSHOT</version>
</plugin>

应该是:

<plugin>
    <groupId>sample.plugin</groupId>
    <artifactId>hello-maven-plugin</artifactId>
    <version>1.1.1</version> <!-- This is the version defined in hello-maven-plugin -->
    <executions>
        <execution>
            <phase>compile</phase>
            <goals>
                <goal>touch</goal> <!-- You declared one goal touch in your plugin, not "sayhi" -->
            </goals>
        </execution>
    </executions>
</plugin>

此外,在使用它编译项目之前,您需要确保安装 Maven 插件(通过 运行 mvn clean install 在插件上)。

另请注意,您的插件只声明了一个目标,即 touch。这是由 Mojo 上的注释 @Mojo( name = "touch", defaultPhase = LifecyclePhase.PROCESS_SOURCES ) 声明的。因此,您不能使用目标 sayhi.