docjunior.de
News
20.03.2013
Habe einen UART auf dem Tiny25 gebraucht. Gab keinen. Hab mir selber einen gebaut.

14.09.2011
Ich habe mich entschieden euch ein Geheimnis zu verraten: Ich hab ein Buch geschrieben: Mikrocontroller in Kürze

Menu
zurück
Gästebuch
eM@il
Sitemap
Logindaten
Benutzername

Passwort


Sie sind der
60676. Besucher
home/ Programmierung/ Java/ maven-Plugins/
 
Index    Was ist das
   maven baut maven-Plugins
   was haben wir getan
   Die pom xml
   Die generierte Java-Klasse
   making it run
   Ein zweiter Blick in den Quellcode
   Plugin-Konfigurationen
   Weitere Informationen

Was ist das maven ist ein hochgradig konfigurierbares und erweiterbares Werkzeug. Die Plugin-Central ist inzwischen bei einer Größe von ca 20GB(!) angekommen und wächst ständig weiter. Dennoch ist es möglich, dass eine benötigte Funktionalität nicht vorhanden ist. Was dann?
Maven bietet hier eine API zur einfachen Erstellung von Plugins.

Hier möchte ich beschreiben, wie man eigene Plugins baut.


maven baut maven-Plugins Der einfachste Weg, an alles zu kommen, was man zum Erstellen von maven-Plugins kommt ist, maven zu beauftragen, alles Notwendige zu besorgen.

Das maven-archetype-plugin kennt einen entsprechenden Archetypen:

mvn archetype:create -DgroupId=de.docjunior.maven -DartifactId=maven-docjunior-plugin -DarchetypeArtifactId=maven-archetype-mojo

Damit haben wir ein neues Maven-Projekt angelegt, mit dem wir spielen können.


was haben wir getan Das Ergebnis unserer Tat ist folgende Dateistruktur:

¦   pom.xml
¦
+---src
    +---main
        +---java
            +---de
                +---docjunior
                    +---maven
                            MyMojo.java

Die POM-XML beinhaltet im Gegensatz zur Standard-POM die Abhängigkeit zur maven-plugin-api. Auch das Packaging sieht anders aus.


Die pom xml "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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>de.deutscherv.maven</groupId>
  <artifactId>maven-instxml-plugin</artifactId>
  <packaging>maven-plugin</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Maven Mojo Archetype</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-plugin-api</artifactId>
      <version>2.0</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>


Die generierte Java-Klasse package de.docjunior.maven;

/*
 * 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 java.io.File;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Goal which touches a timestamp file.
 *
 * @goal touch
 * 
 * @phase process-sources
 */
public class MyMojo
    extends AbstractMojo
{
    /**
     * Location of the file.
     * @parameter expression="${project.build.directory}"
     * @required
     */
    private File outputDirectory;

    public void execute()
        throws MojoExecutionException
    {
        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
                }
            }
        }
    }
}


making it run ..aber was macht das Ganze jetzt?
Wir kompilieren das Ganze und installieren es in unserem lokalen Repository:

mvn install

Anschließend bauen wir uns ein neues Projekt

mvn archetype:create -DgroupId=de.docjunior.test -DartifactId=plugintest

Jetzt muss nur noch unser Plugin eingebunden werden:

..
<build>
<plugins>
<plugin>
<groupId>de.docjunior.maven</groupId>
<artifactId>maven-instxml-plugin</artifactId>
</plugin>
</plugins>
</build>
..


So weit, so gut. Aaaaber wie startet man das Ganze jetzt?


Ein zweiter Blick in den Quellcode Schaut man sich den Quellcode genauer an, stößt man auf folgenden Kommentarblock für die Klasse.

/**
* Goal which touches a timestamp file.
*
* @goal touch
*
* @phase process-sources
*/

Wer glaubt, dass man das goal einfach angeben muss, der liegt richtig:

mvn docjunior:touch

Und schon bekommt man das heiß begehrte "BUILD SUCCESSFULL". Aber was ist passiert?

Wenn wir uns den target-Ordner anschauen, sehen wir etwas interessantes: eine Datei namens touch.txt. Wer den Quellcode richtig deutet, weiß inzwischen, dass das Plugin dafür verantwortlich ist.

Die execute-Methode wird also gestartet, sowie das für das Plugin angegebene @goal aufgerufen wurde. Möchte man einem Plugin-Projekt mehrere Funktionen zuordnen, macht man das im Allgemeinen über unterschiedliche Mojo-Klassen mit entsprechenden goals.

Anmerkung: Zum Start eines Plugins gehört immer eine Phase. Wer kann mir sagen, in welcher Phase dieses Plugin gestartet wird?


Plugin-Konfigurationen Ein Plugin soll natürlich auch anpassbar sein. Hierfür sieht maven standardmäßig die -Tags vor.
Wie bekommen wir jetzt aber den Parser konfiguriert, dass er auf unsere Konfigurationen reagiert?

Die Antwort ist simpel: Das Mojo weiß es.
Über Annotations kann man Instanzvariablen als Parameter deklarieren:
/**
* Location of the file.
* @parameter expression="${project.build.directory}"
* @required
*/
private File outputDirectory;

In diesem Falle ist der Parameter sogar zwingend erforderlich.
In unserer build-Konfiguration sieht das Ganze so aus:

..
<build>
<plugins>
<plugin>
<groupId>de.docjunior.maven</groupId>
<artifactId>maven-instxml-plugin</artifactId>
<b><configuration>
<outputDirectory>c:temp</outputDirectory>
</configuration></b>
</plugin>
</plugins>
</build>
..

ruft man jetzt das goal erneut auf, wird die touch.txt unter dem konfigurierten Pfad abgelegt.

Alternativ funktioniert auch der Aufruf

mvn docjunior:touch -DoutputDirectory=c:testdir
Man beachte, dass das Verzeichnis existieren sollte.


Weitere Informationen Im Online-Werk "better builds with maven" (siehe mein maven tutorial) ist den maven Plugins ein ganzes Kapitel (Kapitel 5) gewidmet.
Mein tutorial sollte hier nur einen Einstieg bieten.
Gern werde ich es aber auf Anfrage auch erweitern.


cmsJr by Jens Rapp, 2006 - 2008