最近、いろいろテストやチュートリアルの学習用にsimple spring web mavenをベースに独自のパッケージ構成や、フォルダ構成にした上で使う場合が多いのですが、さすがに毎回の作業は手間です。
そこで、雛形を作成するようなものはないかと調べてみると、Archetypeを独自に作成することが出来るらしい。
・・というわけで、いろいろやってみたことのメモです(あくまで、自分用のメモです)。

 

 

  • IDEは、STS3.9.6
  • 作業したMavenのバージョンは3.5.4(Mavenのインストール等は割愛)。
  • web.xml<display-name></display-name>artifactIdを挿入する。
  • パッケージの構成を、groupId.artifactIdみたいにする。
  • src/resources配下に、artifactIdを冠するファイルを配置したい。
  • etc..

 

空のArchetypeの作成

cd /work
mvn archetype:generate -B -DarchetypeArtifactId=maven-archetype-archetype \
  -DgroupId=com.example \
  -DartifactId=spring-web-custom \
  -Dversion=1.0-SNAPSHOT
  • -DarchetypeArtifactId=maven-archetype-archetype:Mavenが提供している新しいカスタムarchetypeを作成するためのArchetype。

  • 出来上がったディレクトリ、spring-web-customに移動し、mvn eclipse:eclipseコマンドを発行して、eclipseで使えるようにする。

cd spring-web-custom
mvn eclipse:eclipse
  • Eclipseにインポートする。

 

Eclipse上での作業

インポート直後のフォルダ構成

  • 雛形は、archetype-resources/以下に作っていく。
`-- spring-web-custom
    |-- src/main/resources/
    |   |-- archetype-resources/
    |   |   |-- src/
    |   |   |   |-- main/
    |   |   |   |   `-- java/
    |   |   |   |       `-- App.java
    |   |   |   `-- test/
    |   |   |       `-- java/
    |   |   |           `-- AppTest.java
    |   |   `-- pom.xml
    |   `-- META-INF/
    |       `-- maven/
    |           `-- archetype.xml
    |-- target/
    |-- .classpath
    |-- .project
    `-- pom.xml

 

最終的にプロジェクトに展開した際のフォルダ構成を、このようにしたい。

`-- someapplication
    |-- src/main/java/
    |   `-- com.example.someapplication/
    |       |-- app/
    |       |   `-- HelloController.java
    |       |-- domain/
    |       |   |-- model/
    |       |   |-- repository/
    |       |   `-- service/
    |       `-- App.java
    |-- src/test/java/
    |   `-- com.example.someapplication/
    |       `-- AppTest.java
    |-- src/main/resources/
    |   `-- META-INF/
    |       `-- spring/
    |           |-- someapplication-domain.xml
    |           |-- applicationContext.xml
    |           |-- application.properties
    |           `-- spring-mvc.xml
    |-- src/
    |   `-- main/
    |       `-- webapp/
    |           `-- WEB-INF/
    |               |-- view/
    |               |   `-- showMessage.jsp
    |               `-- web.xml
    |-- target/
    |-- .classpath
    |-- .project
    `-- pom.xml

 

雛形にファイルやディレクトリを配置していく。pom.xmlは、archetype-resources/直下のpomを編集する。

`-- spring-web-custom
    |-- src/main/resources/
    |   |-- archetype-resources/
    |   |   |-- src/
    |   |   |   |-- main/
    |   |   |   |   |-- java/
    |   |   |   |   |   |-- app/
    |   |   |   |   |   |   `--HelloController.java
    |   |   |   |   |   |-- domain/
    |   |   |   |   |   |   |-- model/
    |   |   |   |   |   |   |-- repository/
    |   |   |   |   |   |   `-- service/
    |   |   |   |   |   `-- App.java
    |   |   |   |   |-- resources/
    |   |   |   |   |   `-- META-INF/
    |   |   |   |   |       `-- spring/
    |   |   |   |   |           |-- __projectName__-domain.xml
    |   |   |   |   |           |-- applicationContext.xml
    |   |   |   |   |           |-- application.properties
    |   |   |   |   |           `-- spring-mvc.xml
    |   |   |   |   `-- webapp/
    |   |   |   |       `-- WEB-INF/
    |   |   |   |           |-- view/
    |   |   |   |           |   `-- showMessage.jsp
    |   |   |   |           `-- web.xml
    |   |   |   `-- test/
    |   |   |       `-- java/
    |   |   |           `-- AppTest.java
    |   |   `-- pom.xml
    |   `-- META-INF/
    |       `-- maven/
    |           `-- archetype.xml
    |-- target/
    |-- .classpath
    |-- .project
    `-- pom.xml

最終的に出力されるパッケージのフォルダ構成と、雛形で作成しているフォルダ構成の違いに注意。

その辺は、後でarchetype.xml(実際にはarchetype-metadata.xml)で設定をする。

 

archetype-metadata.xmlの編集

雛形を作成した当初は、archetype.xmlとなっているが、名前をarchetype-metadata.xml に変えて、内容を全て消去し、次のようにする。

<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor
xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd"
name="basic">
    <requiredProperties>
        <requiredProperty key="projectName">
            <defaultValue>${artifactId}</defaultValue>
        </requiredProperty>
        <requiredProperty key="package">
            <defaultValue>${groupId}.${artifactId}</defaultValue>
        </requiredProperty>
        <requiredProperty key="groupIdToPath">
            <defaultValue>com/example</defaultValue>
        </requiredProperty>
    </requiredProperties>

    <fileSets>
        <fileSet filtered="true" packaged="true" encoding="UTF-8">
            <directory>src/test/java</directory>
        </fileSet>
        <fileSet filtered="true" encoding="UTF-8">
            <directory>src/main/resources/META-INF/spring</directory>
            <includes>
                <include>**/*</include>
            </includes>
        </fileSet>
        <fileSet filtered="true" encoding="UTF-8">
            <directory>src/main/resources/META-INF/mybatis</directory>
            <includes>
                <include>**/*</include>
            </includes>
        </fileSet>
        <fileSet filtered="true" encoding="UTF-8">
            <directory>src/main/resources/META-INF</directory>
            <includes>
                <include>*.xml</include>
            </includes>
        </fileSet>
        <fileSet filtered="true" encoding="UTF-8">
            <directory>src/main/java/__groupIdToPath__/__artifactId__/domain/model</directory>
        </fileSet>
        <fileSet filtered="true" encoding="UTF-8">
            <directory>src/main/java/__groupIdToPath__/__artifactId__/domain/repository</directory>
        </fileSet>
        <fileSet filtered="true" encoding="UTF-8">
            <directory>src/main/java/__groupIdToPath__/__artifactId__/domain/service</directory>
        </fileSet>
        <fileSet filtered="true" packaged="true" encoding="UTF-8">
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.java</include>
            </includes>
        </fileSet>
        <fileSet filtered="true" encoding="UTF-8">
            <directory>src/main/webapp/WEB-INF</directory>
            <includes>
                <include>*.xml</include>
            </includes>
        </fileSet>
        <fileSet filtered="false" encoding="UTF-8">
            <directory>src/main/webapp/WEB-INF</directory>
            <includes>
                <include>**/*</include>
            </includes>
        </fileSet>
    </fileSets>

</archetype-descriptor>

 

<requiredProperties> の設定

archetype-metadata.xmlにプロパティを設定する。

  • プロパティに値を設定しておくことで、ファイル名や、ファイル中のテキストに値を展開できる。
  • この例では、projectName、packages、groupIdToPathに値を設定しています。

例えば、ファイル名に__projectName__-domain.xmlとしておけば、最終展開されたときに、someapplication-domain.xmlと展開される。

また、ファイル中の${projectName}とされている部分も、someapplicationと展開される。例として、あるBean定義ファイルの中の:

<import resource="classpath:/META-INF/spring/${artifactId}-domain.xml" />

は、

<import resource="classpath:/META-INF/spring/someapplication-domain.xml" />

という形で展開される。

上記プロパティの中で、groupIdToPathは、本来であれば${groupId.replaceAll("\\.", "/")}とすればいいのかもしれないが、バグが有るために意図通りに処理されない。(参照 Required property default value incorrect when using system property
このリンクには、修正パッチがある(時間の都合で試していない)。

 

fileSetsの設定

<fileSets>
    <!-- (1)  -->
    <fileSet filtered="true" packaged="true" encoding="UTF-8">
        <directory>src/test/java</directory>
    </fileSet>
    <fileSet filtered="true" encoding="UTF-8">
        <directory>src/main/resources/META-INF/spring</directory>
        <includes>
            <include>**/*</include>
        </includes>
    </fileSet>
    <fileSet filtered="true" encoding="UTF-8">
        <directory>src/main/resources/META-INF</directory>
        <includes>
            <include>*.xml</include>
        </includes>
    </fileSet>
    <!-- (2)  -->
    <!-- (3)  -->
    <fileSet filtered="true" encoding="UTF-8">
        <directory>src/main/java/__groupIdToPath__/__artifactId__/domain/model</directory>
    </fileSet>
    <fileSet filtered="true" encoding="UTF-8">
        <directory>src/main/java/__groupIdToPath__/__artifactId__/domain/repository</directory>
    </fileSet>
    <fileSet filtered="true" encoding="UTF-8">
        <directory>src/main/java/__groupIdToPath__/__artifactId__/domain/service</directory>
    </fileSet>
    <fileSet filtered="true" packaged="true" encoding="UTF-8">
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.java</include>
        </includes>
    </fileSet>
    <fileSet filtered="true" encoding="UTF-8">
        <directory>src/main/webapp/WEB-INF</directory>
        <includes>
            <include>*.xml</include>
        </includes>
    </fileSet>
    <fileSet filtered="false" encoding="UTF-8">
        <directory>src/main/webapp/WEB-INF</directory>
        <includes>
            <!-- (4) -->
            <include>**/*</include>
        </includes>
    </fileSet>
</fileSets>
番号 説明
(1) filteredpackagedencodingの各属性がある。
(2) プロパティのキーを__(アンダーバー2つ)で囲むことで、値に変換される。(${artifactId}は、その文字のままになる)
(3) 何も指定していないと、空のディレクトリはコピーされないが、このように明示しておくことで、空のディレクトリもコピーされる。
(4) 指定されているディレクトリ内の、全てのディレクトリの配下にある全てのディレクトリ、ファイル。

 

各属性について

属性 タイプ 説明
filtered boolean trueとすることで、ファイルセットをVelocityテンプレートとしてフィルタリングして、プロパティの値に置き換えられます。falseの場合は、何も変更が加えられず、ただ単にコピーされます。
デフォルトはtrue
packaged boolean trueとすることで、選択されたファイルは${package}プロパティで表されるディレクトリ構造内にコピーされます。今回の例の場合、パッケージ名はcom.example.someapplicationなので、ディレクトリ、com/example/sommeaplication/(存在しない場合は、ディレクトリが作成される)にコピーされる。
デフォルトはfalse
encoding String 内容をフィルタリングする際のエンコーディング

 

雛形に配置している.javaファイルの内容

App.java

package ${package};

/**
 * Hello world!
 *
 */
public class App
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}
  • この${package}は、com.example.someapplicationと展開される。

実際の雛形では、src/main/java/App.javaとなっているが、${package}で指定して、<fileset>filtered="true"とすることで、プロジェクトに展開したときに、src/main/java/com/example/someapplication/App.javaに配置される。

 

HelloController.java

package ${package}.app;

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {

    @RequestMapping("")
    public String hello(
            @AuthenticationPrincipal UserDetails userdetails,
            Model model) {
        model.addAttribute("message", userdetails.toString());
        return "showMessage";
    }

}
  • HelloController.javaは、${package}.appとすることで、相対的なパッケージ名になるようにしている。

 

ローカルリポジトリにインストール

mvn clean;mvn package;mvn install

 

作成したArchetypeをベースにプロジェクト作成

次のようにして、作成した自前の ArcheType をひな形にしてプロジェクトを作成します。

mvn archetype:generate -DarchetypeGroupId=com.example \
    -DarchetypeArtifactId=spring-web-custom \
    -DarchetypeVersion=0.0.1 \
    -DgroupId=com.example \
    -DartifactId=demospring

Eclipse にインポートする場合は、先程のコマンドで作成されたディレクトリ (例: demospring/) に移動して、

mvn eclipse:eclipse

を実行します。

 

PowerShell を使用されている場合は要注意!!

ただし、もし Microsoft の PowerShell を使用している場合は、プロジェクト作成時のコマンドを次のように各オプションを ダブルクォーテーション (") で囲まないと、作成に失敗します。

mvn archetype:generate -DarchetypeGroupId=com.example \
    "-DarchetypeArtifactId=spring-web-custom" \
    "-DarchetypeVersion=0.0.1" \
    "-DgroupId=com.example" \
    "-DartifactId=demospring"

 

 
カテゴリー: Java

zaturendo

中小企業社内SE。

0件のコメント

コメントを残す

アバタープレースホルダー

メールアドレスが公開されることはありません。 が付いている欄は必須項目です