tokuhirom's Blog

maven archetype の作り方

Java の世界では maven archetype を作成して、それを使って行うのが基本となっている。

なんだかめんどくさそうなので LL で生成していたのだが、やはりその LL のスクリプトをインストールさせる方法が特になく、辛い。

ということで諦めて maven archetype の作成方法を学ぶことにしたわけであります。


maven archetype の作成方法は公式サイトのこのあたりにのっています。 http://maven.apache.org/guides/introduction/introduction-to-archetypes.html

archetype は velocity を用いて生成されます。

チュートリアルがここにあるので、これを順番にやっていけばそれなりのことはできる。 http://maven.apache.org/guides/mini/guide-creating-archetypes.html

最低限の前提として以下のようなディレクトリ構成となっていることを覚えておく必要がある。

pom.xml
src/main/resources/META-INF/maven/archetype.xml
src/main/resources/archetype-resources/ この中にテンプレートを入れる

pom.xml がいわゆるいつもの pom.xml であって、いつもどおりに作成すればよい。

src/main/resources/META-INF/maven/archetype.xml が archetype の設定ファイルであり、ここにこまかな設定を書けばいい。

チュートリアルに書いてある例だと以下のようになっている。

    <archetype xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype/1.0.0 http://maven.apache.org/xsd/archetype-1.0.0.xsd">
        <id>quickstart</id>
        <sources>
            <source>src/main/java/App.java</source>
        </sources>
        <testSources>
            <source>src/test/java/AppTest.java</source>
        </testSources>
    </archetype>

ここで、ディレクトリ構成は以下のようになっている、と。

archetype
|-- pom.xml
`-- src
    `-- main
        `-- resources
            |-- META-INF
            |   `-- maven
            |       `--archetype.xml
            `-- archetype-resources
                |-- pom.xml
                `-- src
                    |-- main
                    |   `-- java
                    |       `-- App.java
                    `-- test
                        `-- java
                            `-- AppTest.java

ここからたとえば com.example.foo プロジェクトを生成しようとしたら src/main/java/com/example/foo/App.java にファイルが生成されてほしいとか思うわけだが、その辺は sources に書いてある時点で、よしなに配置してくれる。

src/main/resources/archetype-resources/pom.xml は以下のように記述すれば、よい。${groupId} のようになっている部分はコード生成時に置換される。

<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>${groupId}</groupId>
    <artifactId>${artifactId}</artifactId>
    <version>${version}</version>
    <packaging>jar</packaging>

    <name>A custom project</name>
    <url>http://www.myorganization.org</url>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

できあがったら、あとは

    mvn install

として、~/.m2/repository/ にコピーする。以下のコマンドで試せる。

    mvn archetype:generate                                  \
        -DarchetypeGroupId=<archetype-groupId>                \
        -DarchetypeArtifactId=<archetype-artifactId>          \
        -DarchetypeVersion=<archetype-version>                \
        -DgroupId=<my.groupid>                                \
        -DartifactId=<my-artifactId>

と、ここまでが tutorial の内容である。

チュートリアルだけでリファレンスがないよ?

見当たらないけど、なんかググれば stackoverflow が出てきてなんとかなるよ。

README.md も生成したいよ?

README.md とかを生成させる方法がさっぱりわからないのだが、これは簡単。

osrc/main/resources/META-INF/maven/archetype.xml で resource として指定してあげればOK。その他の、うまくコピーされないファイルもだいたい resource 指定でいけそう。

<?xml version="1.0" encoding="UTF-8"?>
<archetype xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype/1.0.0 http://maven.apache.org/xsd/archetype-1.0.0.xsd">
    <id>avans-setup</id>
    <resources>
        <resource>src/main/webapp/WEB-INF/web.xml</resource>
        <resource>src/main/resources/templates/index.mustache</resource>
        <resource>README.md</resource>
    </resources>
</archetype>

archetype 側のバージョンを埋め込んだりしたい

archetype を単体でリリースする場合もあるが、フレームワークと同じレポジトリで管理され archetype は sub project として管理されている場合も多い。その場合、archetype で生成する pom.xml では最新版を常に指定したい。

たとえば avans の場合だと以下のようなディレクトリ構成となっていて、parent pom でバージョン番号を指定している。

avans/pom.xml   ← parent pom
avans/avans/pom.xml
avans/avans-setup/pom.xml

このような場合、どうやって

avans/avans-setup/src/main/resources/archetype-resources/pom.xml

にバージョン情報を伝えたらよいか。

avans/avans-setup/pom.xml に以下のような記述をする。これにより、src/main/resources の中のファイルの @jetty.version@ のような記述の部分にバージョン番号などが埋め込み可能となる。

<build>
    <plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.6</version>
        <configuration>
        <!-- Redefining delimiters. So that we can filter the -->
        <!-- archetype resources. -->
        <!-- The regular delimiter is already used by the archetype -->
        <!-- generation process.  -->
        <!-- By redefining the delimimter we can access  -->
        <!-- variables like @jetty.version@ or @project.version@ -->
        <useDefaultDelimiters>false</useDefaultDelimiters>
        <delimiters>
            <delimiter>@</delimiter>
        </delimiters>
        </configuration>
    </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*</include>
            </includes>
        </resource>
    </resources>
</build>

この状態で、src/main/resources/archetype-resources/pom.xml に以下のように記述すればよい。

<modelVersion>4.0.0</modelVersion>
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>${artifactId}</name>
<description></description>
<packaging>war</packaging>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <avans.version>@project.version@</avans.version>
    <tomcat.version>7.0.56</tomcat.version>
</properties>

ひな形いじるのが辛いよ、って人~

こういうふうに、sed で置換してひな形つくるのが良いとのこと。

https://github.com/making/spring-boot-blank/blob/master/create-maven-archetype.sh

まとめ

maven archetype 思ったより使いやすい。maven 動かしまくるから動作確認にやや時間がかかるが、それを除けば快適である。

社内向けの archetype も社内 maven repo にあげておけばいい。