3.5. 開発プロジェクトのビルド¶
目次
3.5.1. 開発プロジェクトのビルド¶
アプリケーションサーバにデプロイするためのwarファイル、envモジュール(ファイル環境依存ファイルを格納するモジュール)のjarファイルを作成する方法を紹介する。
Maven Archetypeで作成したプロジェクトでは、warファイルを作成する方法として以下の2つの方法を提供している。
Note
推奨するビルド方法について
本ガイドラインでは、envモジュールのjarファイルをwarファイルに含めないビルド方法 を推奨している。 なお、ここで紹介するビルド方法は選択肢の一つであり、他のビルド方法を採用してもよい。
ただし、試験環境や商用環境にリリースするwarファイルとjarファイルは、EclipseなどのIDEが提供している機能を使って作成しないようにすること。 Eclipseなどの一部のIDEでは、開発用に最適化された独自のコンパイラを使ってクラスファイルを作成しており、 コンパイラの違いが原因でアプリケーション実行時に予期しないエラーが発生するリスクが生まれる。
Note
プロジェクト構成の原則
原則として下記のようなプロジェクト構造とする。
- 必ずマルチプロジェクト構成にする。
- 一つのプロジェクトに環境依存性のある設定ファイル(ex. logback.xml, jdbc.properties)をできるだけ集約する。 以降、このプロジェクトを *-env と表現する。
- ex. terasoluna-tourreservation-env
- *-env以外のプロジェクトには環境依存性のある設定値を一切持たせない。
- もちろん、src/test/resources 配下などにテスト用の環境依存性設定ファイルを格納しておくことは許可される。
- 全てのソフトウェアのパッケージ済みバイナリをパッケージリポジトリ上に保管して管理する。
- *.jarファイルだけではなく*.warファイルも成果物としてパッケージリポジトリにデプロイする。したがって、それらのjar/warファイルには環境依存性が含まれていてはならない。
- *-env プロジェクトは下記のような構造にする。
- 開発者のPC上での作業に必要な設定値をデフォルトとして src/main/resources 配下のファイルに格納する。
- 試験サーバ、本番サーバ等、環境毎に異なる設定ファイルを src/main/resources 以外(ex. configs/test-server)のフォルダに格納し、mavenのprofile機能を使って環境毎に自動的に設定値を差し替えながら *-env-x.y.z.jarファイルをビルドする。
上記のような構造を取ることにより、ソフトウェアライフサイクルの全ての場面において、適切に開発をすることができるようになる。
- ローカル開発環境では、プロジェクト本体と*-envプロジェクトの両方をチェックアウトし、envプロジェクトを本体プロジェクトのビルドパスに含めることによって、ローカル開発環境でのコーディングとテストを可能にする。
- CIサーバ上ではビルドツール(maven)によるテストの実行とパッケージングを行い、必要に応じてパッケージリポジトリにartifactをdeployする。
- 試験サーバ、本番サーバでは、パッケージリポジトリにあらかじめ保管しているプロジェクト本体に、リリース先環境にあわせてビルドした*-envプロジェクトを追加してリリースすることにより、アプリケーションの動作が可能になる。
詳細についてはサンプルアプリケーションを参考にされたい。
Warning
ビルド環境について
ここではWindows環境でビルドする例になっているが、Windows環境でビルドすることを推奨しているわけではない。 本ガイドラインでは、アプリケーションの実行環境と同じOSとJDKのバージョンを使ってビルドすることを推奨する。
[Windowsの場合]
echo %JAVA_HOME%
set JAVA_HOME={Please set home directory of JDK}
[Linux系の場合]
echo $JAVA_HOME
JAVA_HOME={Please set home directory of JDK}
Note
環境変数「JAVA_HOME」は、ビルドを実行するOSユーザーのユーザー環境変数に設定しておくとよい。
3.5.1.1. envモジュールのjarファイルをwarファイルに含めないビルド方法¶
3.5.1.1.1. warファイルの作成¶
開発プロジェクトのルートディレクトリへ移動する。
cd C:\work\todo
-P
パラメータ)にwarpack
を指定して、Maven installを実行する。mvn -P warpack clean install
C:\work\todo\todo-web\target\todo-web.war
)Note
指定するゴールについて
上記例ではゴールにinstall
を指定してwarファイルをローカルリポジトリへインストールしているが、
- warファイルの作成のみ行う場合はゴールに
package
- Nexusなどのリモートリポジトリへデプロイする場合はゴールに
deploy
を指定すればよい。
3.5.1.1.2. envモジュールのjarファイルの作成¶
envモジュールのディレクトリへ移動する。
cd C:\work\todo\todo-env
Mavenのプロファイル(-P
パラメータ)に環境を識別するプロファイルIDを指定して、Maven packageを実行する。
mvn -P test-server clean package
C:\work\todo\todo-env\target\todo-env-1.0.0-SNAPSHOT-test-server.jar
)Note
環境を識別するプロファイルIDについて
Maven Archetypeで作成したプロジェクトでは、以下のプロファイルIDがデフォルトで定義されている。
local
: 開発者のローカル環境向け(IDE開発環境向け)のプロファイル (デフォルトのプロファイル)test-server
: 試験環境向けのプロファイルproduction-server
: 商用環境向けのプロファイル
デフォルトで用意しているプロファイルは上記の3つだが、開発するシステムの環境構成にあわせて追加及び修正されたい。
3.5.1.2. envモジュールのjarファイルをwarファイルに含めるビルド方法¶
3.5.1.2.1. warファイルの作成¶
Warning
envモジュールのjarファイルをwarファイルに含める場合の注意点
envモジュールのjarファイルをwarファイルに含めた場合、warファイルを他の環境にデプロイすることができないため、 間違って他の環境(特に商用環境)にデプロイされないようにwarファイルを管理すること。
また、環境毎にwarファイルを作成して各環境へリリースする方法を採用した場合、 商用環境へリリースされるwarファイルが厳密にいうとテスト済みのwarファイルではないという点を意識してほしい。 これは、商用環境用のwarファイルを作成する際にコンパイルをしなおすためである。 warファイルを環境毎に作成してリリースする場合は、GitやSubversionなどのVCS(Version Control System)の機能(タグ機能など)を活用し、 テスト済みのソースファイルを使用して商用環境や各種テスト環境へリリースするwarファイルを作成する仕組みを確立することが特に重要である。
開発プロジェクトのルートディレクトリへ移動する。
cd C:\work\todo
-P
パラメータ)にwarpack-with-env
とenvモジュールの中で定義している環境を識別するプロファイルIDを指定して、Maven packageを実行する。mvn -P warpack-with-env,test-server clean package
C:\work\todo\todo-web\target\todo-web.war
)3.5.1.3. デプロイ¶
3.5.1.3.1. Tomcatへのデプロイ¶
WebアプリケーションをTomcat上にリリースする場合は次のような手順をとる。
- リリース対象のAPサーバ環境にあわせてmavenのprofileを指定し、 *-env プロジェクトを ビルドする。
- 上記でビルドした*-env-x.y.z.jarファイル をあらかじめ決定したAPサーバ上のフォルダに設置する。 ex. /etc/foo/bar/abcd-env-x.y.z.jar
- あらかじめパッケージリポジトリにデプロイ済みの*.warファイルを [CATALINA_HOME]/webapps 配下で解凍(unjar)する。
- Tomcat 7を使用する場合は、TomcatのVirtualWebappLoader機能を使用して /etc/foo/bar/*.jar をクラスパスに追加する。
- [CATALINA_HOME]/conf/[contextPath].xml ファイルに下記の定義を追加する。
- 詳しくは、 http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/loader/VirtualWebappLoader.html と terasoluna-tourreservation-envのconfigsフォルダを参考されたい。
- VirtualWebappLoaderの設定例:
<Loader className="org.apache.catalina.loader.VirtualWebappLoader" virtualClasspath="/etc/foo/bar/*.jar" />
- なお、VirtualWebappLoader機能はTomcat 6でも使用可能。
- Tomcat 8.xを使用する場合は、Tomcatのリソース機能を使用して /etc/foo/bar/*.jar をクラスパスに追加する。
- [CATALINA_HOME]/conf/[contextPath].xml ファイルに下記の定義を追加する。
- 詳しくは、 https://tomcat.apache.org/migration-8.html#Web_application_resources と terasoluna-tourreservation-envのconfigsフォルダを参考されたい。
- リソースの設定例:
<Resources className="org.apache.catalina.webresources.StandardRoot"> <PreResources className="org.apache.catalina.webresources.DirResourceSet" base="/etc/foo/bar/" internalPath="/" webAppMount="/WEB-INF/lib" /> </Resources>
Note
- [CATALINA_HOME]/conf/server.xml の Host タグ上の autoDeploy 属性を false にセットしておかなければならない。さもないとwebアプリケーションの再起動のたびに[CATALINA_HOME]/conf/[contextPath].xmlが自動的に削除されてしまう。
- autoDeployを無効化している場合、[CATALINA_HOME]/webappsにwarファイルを置くだけではWebアプリケーションは起動しない。必ずwarファイルをunjar(unzip)すること。
3.5.1.3.2. Tomcat以外のアプリケーションサーバへのデプロイ¶
アプリケーションサーバとしてTomcat以外のサーバを使用する際のデプロイ方法(手順)を紹介する。
TomcatのVirtualWebappLoaderのように、Webアプリケーションごとにクラスパスを追加する手段が提供されていない アプリケーションサーバ(例: WebSphere,WebLogic,JBoss)にリリースする場合には、 *-env-x.y.z.jarファイルをwarファイル内の WEB-INF/lib 配下に追加してからリリースする方法が最も簡単である。
- リリース対象のAPサーバ環境にあわせてmavenのprofileを指定し、 *-env プロジェクトを ビルドする。
- あらかじめパッケージリポジトリにデプロイ済みの*.warファイルを 作業ディレクトリにコピーする。
- 下のように、jarコマンドの追加オプションを利用して、warファイル内の WEB-INF/lib の配下に追加する。
- foo-x.y.z.warをAPサーバにリリースする。
Note
warファイルをアプリケーションサーバへデプロイする方法は、使用するアプリケーションサーバのマニュアルを参照されたい。
ここでは、jarコマンドを使用して、envモジュールのjarファイルをwarファイルに組み込む方法(手順)を紹介する。
cd C:\work\todo\todo-env
install
またはdeploy
している前提とする)mvn org.apache.maven.plugins:maven-dependency-plugin:2.5:get^
-DgroupId=com.example.todo^
-DartifactId=todo-web^
-Dversion=1.0.0-SNAPSHOT^
-Dpackaging=war^
-Ddest=target/todo-web.war
C:\work\todo\todo-env\target\todo-web.war
)Note
-DgroupId
、-DartifactId
、-Dversion
、-Ddest
には、適切な値を指定すること。- Linux系で実行する場合は、行末の “
^
” を “\
” に読み替えること。
作成したjarファイルを作業ディレクト(target\WEB-INF\lib
)へ一旦コピーし、warファイルの中に追加する。
[Windowsの場合]
mkdir target\WEB-INF\lib
copy target\todo-env-1.0.0-SNAPSHOT-test-server.jar target\WEB-INF\lib\.
cd target
jar -uvf todo-web.war WEB-INF\lib
[Linux系の場合]
mkdir -p target/WEB-INF/lib
cp target/todo-env-1.0.0-SNAPSHOT-test-server.jar target/WEB-INF/lib/.
cd target
jar -uvf todo-web.war WEB-INF/lib
Note
jarコマンドが見つからない場合の対処
jarコマンドが見つからない場合は、以下のいずれかの対処を行うことで解決することができる。
JAVA_HOME/bin
を環境変数「PATH」に追加する。- jarコマンドをフルパスで指定する。Windowの場合は
%JAVA_HOME%\bin\jar
、Linux系の場合は${JAVA_HOME}/bin/jar
を指定すればよい。
3.5.1.3.3. 継続的なデプロイ¶
プロジェクト(ソースコードツリー)の構造、バージョン管理、インスペクションとビルド作業、ライフサイクル管理の工程を恒常的にループさせることによって目的のソフトウェアをリリースし続けることが、継続的デプロイメントである。
開発の途中では、SNAPSHOTバージョンのソフトウェアをパッケージリポジトリや開発用APサーバにリリースし、テストを実施する。 ソフトウェアを正式にリリースする場合には、バージョン番号を固定したうえでVCSのソースコードツリーに対してタグづけを行う必要がある。 このように、スナップショットリリースの場合と正式リリースの場合で、ビルドとデプロイのフローが少し異なる。
また、Webサービスを提供するAPサーバにアプリケーションをデプロイする場合には、スナップショットバージョンか正式リリースバージョンかに関わらず、 デプロイ先のAPサーバ環境に合わせた環境依存性設定ファイル群と*.warファイルをセットでデプロイする必要がある。
そこで、環境依存性設定を持たない状態のライブラリ(jar,war)をmavenリポジトリに登録する作業と、 それらを実際にAPサーバにデプロイする作業を分離することによって、デプロイ作業を簡潔に実施可能にする。
Note
mavenの世界では、pom.xml上の<version>タグの内容によってそれがSNAPSHOTバージョンなのかRELEASEバージョンなのかが自動的に判別される。
- 末尾が -SNAPSHOT である場合にSNAPSHOTとみなされる。例:<version>1.0-SNAPSHOT</version>
- 末尾が -SNAPSHOT ではない場合はRELEASEとみなされる。例:<version>1.0</version>
また、mavenパッケージリポジトリにはsnapshotsリポジトリとreleaseリポジトリの2種類があり、いくつかの制約があることに注意する。
- SNAPSHOTバージョンのソフトウェアをreleaseリポジトリに登録することはできない。その逆も不可能。
- releaseリポジトリには、同一のGAV情報を持つartifactは1回しか登録できない。(GAV=groupId,artifactId,version)
- snapshotリポジトリには、同一のGAV情報を持つartifactを何度でも登録しなおすことができる。
3.5.1.3.3.1. SNAPSHOTバージョンの運用¶
SNAPSHOTバージョンのソフトウェアのデリバリーフローは下図のように簡潔である。
- 開発用trunkからソースコードをチェックアウトする。
- コンパイル、コードメトリクスの測定、テストを実行する。
- コンパイルエラー、コードメトリクスでの一定以上のviolationの発生、テストの失敗の場合、以降の作業を中止する。
3. mavenパッケージリポジトリサーバにartifact(jar,warファイル)をアップロード(mvn deploy)する。 |
3.5.1.3.3.2. RELEASEバージョンの運用¶
正式なリリースの場合、バージョン番号の付与作業が必要なため、SNAPSHOTリリースよりもやや複雑なフローとなる。
- リリースに与えるバージョン番号を決定する。(例:1.0.1)
- 開発用trunk(またはリリース用branch)からソースコードをチェックアウトする。
- pom.xml上の<version>タグを変更する。(例:<version>1.0.1</version>)
- VCS上にtagを付与する。(例: tags/1.0.1)
- コンパイル、コードメトリクスの測定、テストを実行する。
- コンパイルエラー、コードメトリクスでの一定以上のviolationの発生、テストの失敗の場合、以降の作業を中止する。
- 失敗した場合はVCS上のtagを削除する。
- mavenパッケージリポジトリサーバにartifact(jar,warファイル)をアップロード(mvn deploy)する。
Todo
ここで最後にtrunkのソースツリーのpom.xmlのversionタグを、 次のSNAPSHOTバージョンに書き変えてコミットするところまで書くべきか?!
Note
pom.xmlファイルの<version>タグの変更は versions-maven-plugin で可能である。
mvn versions:set -DnewVersion=1.0.0
上記のようなコマンドで、pom.xml内のversionタグを<version>1.0.0</version>のように編集することができる。
3.5.1.3.3.3. アプリケーションサーバへのリリース¶
Webサービスを提供するAPサーバにアプリケーションをリリースする場合、 あらかじめmavenパッケージリポジトリに登録済みのwarファイルと、 リリース先のAPサーバ環境に合わせた環境依存性設定ファイル群とを、セットでリリースする。 これはスナップショットリリースか正式リリースかに関わらず同じフローとなる。
- リリース対象バージョンのwarファイルをmavenパッケージリポジトリからダウンロードする
- *-resourcesプロジェクト(環境依存性設定ファイルを集約しているプロジェクト)をVCSからチェックアウトする
- mavenのprofileを機能によって、リリース先の環境に合わせた設定ファイル群で内容を差し替えてresourcesプロジェクトをパッケージし、*-resources-x.y.z.jarを生成する。
- 生成した*-resources-x.y.z.jarファイルを、warファイル内のWEB-INF/libフォルダ配下に追加する。
- Tomcatの場合は、*-resources-x.y.z.jarをwarファイル内部に追加するのではなく、Tomcatサーバ上の任意のパスにコピーし、そのパスをVirtualWebappLoaderの拡張クラスパスに指定する。
- warファイルをアプリケーションサーバにデプロイする。
Note
mavenパッケージリポジトリからのwarファイルのダウンロードは、maven-dependency-pluginのgetゴールで可能である。
mvn org.apache.maven.plugins:maven-dependency-plugin:2.5:get^
-DgroupId=com.example^
-DartifactId=mywebapp^
-Dversion=0.0.1-SNAPSHOT^
-Dpackaging=war^
-Ddest=${WORKSPACE}/target/mywebapp.war
これで、targetというディレクトリ配下にmywebapp.warファイルがダウンロードされる。
さらに、下記のようなコマンドで環境依存設定ファイルのパッケージをmywebapp.warファイル内に追加することができる。
mkdir -p $WORKSPACE/target/WEB-INF/lib
cd $WORKSPACE/target
cp ./mywebapp-resources*.jar WEB-INF/lib
jar -ufv mywebapp.war WEB-INF/lib