本文主要介绍编写自定义maven插件的基本步骤,以及如何打包发布,调用。
项目搭建:
和搭建普通的java项目相同,可以通过 IDE idea 的create from archetype中选择 maven-archetype-mojo即可。也可以自己创建普通的maven项目,自己往里面放要引用的jar包和插件。
下面是项目中用到的jar和插件
<dependencies> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <version>2.0</version> </dependency> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-model</artifactId> <version>2.2.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> <version>2.5.1</version> <configuration> <goalPrefix>hello</goalPrefix> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
其中<goalPrefix>hello</goalPrefix>是为了当我们把插件发布后,调用就可以直接用hello来调用,类是我们经常用到的eclipse:eclipse。前面代表插件,后面代表要执行的maven goal。
要编写maven插件,必须要编写一个MOJO(即Maven old java object),一个普通的maven java类对象。所有的MOJO必须继承AbstractMojo的类。下面是一个HelloMojo类:
package com.yao; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; /** * @goal hello * */ public class HelloMojo extends AbstractMojo { @Override public void execute() throws MojoExecutionException, MojoFailureException { getLog().info("hello maven plugin"); } }
仅仅在调用的时候打印一句话。一定要注意 @goal 就相当有给HelloMojo起了一个名称,这个goal一定不要忘记
然后就是编译打包:
直接在当前项目的根目录下运行:mvn clean install 就把当前的maven插件打到本地的reposity里了。
调用: mvn com.yao:maven-plugin-hello:1.0-SNAPSHOT:hello
首先要写上插件的groupId 然后是插件的名称 版本 ,最后要调用插件的goal。这样调用我们要写很多的东西,可以通过在本地maven setting.xml中添加如下内容
<pluginGroups> <pluginGroup>com.yao</pluginGroup> </pluginGroups>
这样之后我们调用就直接可以用插件代号加goal来调用了:mvn hello:hello
这样maven插件helloworld就完成了。
下面介绍一个稍微复杂的goal,通过在编译代码的时候往源代码的头里加上版权信息。下面是具体代码
package com.yao; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.List; /** * Created by robin on 5/2/15. * @goal copyright * @execute phase=package */ public class CopyRight extends AbstractMojo { private static final String JAVA_SUFFIX=".java"; private static final String COPY_RIGHT="\n"+ "/** CopyRight \n" + "* xxxxxxxxxxxxxxxxx Robin\n" + "* xxxxxxxxxxxxxxxxx Robin\n" + "* END \n"+ "*/\n"; /** * @parameter expression="${project.build.sourceDirectory}" * @required * @readonly */ private File sourcedir; public void execute() throws MojoExecutionException, MojoFailureException { addCopyRight(sourcedir); } private void addCopyRight(File dir){ if(!dir.isDirectory()){ getLog().error(new IllegalArgumentException("源代码目录不对!")); } List<File> javaFiles=new ArrayList<File>(); findJavaFiles(dir,javaFiles); if(javaFiles.size()>0){ for (File file:javaFiles){ addCopyHead(file); } } } private void findJavaFiles(File file,List<File> javaFiles){ getLog().info("scan file:"+file.getAbsolutePath()); if(file.isDirectory()){ for (File child:file.listFiles()){ findJavaFiles(child,javaFiles); } }else { if(file.getName().endsWith(JAVA_SUFFIX)){ javaFiles.add(file); } } } private void addCopyHead(File file){ if(file.isDirectory()){ getLog().error(new IllegalArgumentException("要添加版权头的必须是文件!")); } try(RandomAccessFile randomAccessFile=new RandomAccessFile(file,"rw"); RandomAccessFile tmpFile=new RandomAccessFile(File.createTempFile("copy_right","tmp"),"rw")){ tmpFile.writeBytes(new String(COPY_RIGHT.getBytes("UTF-8"))); randomAccessFile.seek(0); String line=null; while((line=randomAccessFile.readLine())!=null){ tmpFile.writeBytes(new String(line.getBytes("UTF-8"))+"\n"); } randomAccessFile.setLength(0); FileChannel in=tmpFile.getChannel(); FileChannel out=randomAccessFile.getChannel(); in.transferTo(0,tmpFile.length(),out); }catch (Exception e){ getLog().error(e); } } public static void main(String[]args) throws IOException { /* try(RandomAccessFile randomAccessFile=new RandomAccessFile("/home/robin/tmp/blogtmp.txt","rw")){ randomAccessFile.seek(randomAccessFile.length()); randomAccessFile.writeChars(COPY_RIGHT); }catch (Exception e){ }*/ } }
其中要注意
/** * @parameter expression="${project.build.sourceDirectory}" * @required * @readonly */ private File sourcedir;
在maven运行插件的时候直接根据注释会把项目中的sourcedir注入进来,不用我们额外操作。其他的代码不解释了,就是简单的把文件添加上COPY_RIGHT 然后直接copy。其中getLog()可以把相关的信息打印到我们控制台上。
在项目中调用该插件:
<build> <plugins> <plugin> <groupId>com.yao</groupId> <artifactId>maven-plugin-hello</artifactId> <version>1.0-SNAPSHOT</version> <executions> <execution> <id>start-copyright</id> <phase>compile</phase> <goals> <goal>copyright</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
这样在编译的时候会自动把版权信息加到java 源文件上了
demo上传到github:https://github.com/WangErXiao/maven-plugin-hello
END---------------------------------------------------------------------------
转发标注来源:http://my.oschina.net/robinyao/blog/409153