LoginSignup
7
7

More than 5 years have passed since last update.

Mavenのprofilesとmaven-war-pluginを利用して環境に依存しないwarファイルを作る

Posted at

はじめに

マルチモジュールプロジェクトでwebモジュールと環境設定モジュールを別にし環境に依存しないwarファイルを作ってTomcatで実行できるか試してみました。

  • 環境設定とは今回はDBの接続先に限定します。つまり、開発時や検証環境、本番環境と用途ごとに接続先は解れるが、warファイルは同じものを利用できるようにすることが目標です。
  • 考え方はTerasoluna 3.5. 開発プロジェクトのビルドの『envモジュールのjarファイルをwarファイルに含めないビルド方法』をベースにしています。
  • ただし検証に利用するプロジェクトがレガシー過ぎるので、このプロジェクトで対応できる方法で考えました。
  • "xxx"はwebアプリのartifactidです。またversionは0.0.1-SNAPSHOTなので生成されるjarもxxx-env-0.0.1-SNAPSHOT.jarとなりますがVersion表記は省略しています。

目標

  1. webモジュール内の環境設定ファイルを別モジュールに分ける
  2. DBの接続先ごとに設定ファイルを作りprofileを利用してjarを作成する
  3. Webモジュールに環境設定ファイルのpathを通す
  4. webモジュールをTomcatにデプロイする

動作環境

  • Windows7
  • Maven 3.3.9
  • JDK 1.7
  • Tomcat 7
  • Oracle 12.1.0.1
  • IDE:Eclipse 4.7.0

※Tomcatのインストール先は、開発環境(IDEと同じPC)です。

1. webモジュール内の環境設定ファイルを別モジュールに分ける

環境設定ファイルwebapp/WEB-INF/applicationContext.xmlsrc/main/resources/META-INFに移動しても動作することを確認するため、struts-config.xmlのプラグイン「org.springframework.web.struts.ContextLoaderPlugIn」の設定ファイルのパラメータで指定していた/WEB-INF/applicationContext.xmlclasspath*:/META-INF/applicationContext.xmlに変更したところ問題無く動作しました。

そこでマルチモジュールプロジェクト配下に、環境設定用のモジュールxxx-envを作成しapplicationContext.xmlをsrc/main/resources/META-INFに移動し、webモジュール側のdependencyにxxx-env.jarを追加し動作を確認しました。

これによりアプリケーションの環境依存部分を別モジュールに切り分けることができました。

2. DBの接続先ごとに設定ファイルを作りprofileを利用してjarを作成する

xxx-envモジュールに、local(開発)/staging(検証)/prod(本番)の3つを作成し異なるDB接続先を定義したapplicationContext.xmlを用意しました。
* local・・・・src/main/resources/META-INF/applicationContext.xml
* staging・・・configs/staging/resources/META-INF/applicationContext.xml
* prod・・・・configs/prod/resources/META-INF/applicationContext.xml

xxx-envモジュールのpom.xmlで以下のようなprofilesを定義しました。

pom.xml(env)
・・・
<build>
  <finalName>${buildFinalName}</finalName>
  <resources>
    <resource>
      <directory>${resource.directory}</directory>
    </resource>
  </resources>
</build>
<profiles>
  <profile>
    <id>local</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
      <resource.directory>src/main/resources</resource.directory>
      <buildFinalName>${project.artifactId}-${project.version}-dev</buildFinalName>
    </properties>
  </profile>
  <profile>
    <id>staging</id>
    <properties>
      <resource.directory>${basedir}/configs/staging/resources</resource.directory>
      <buildFinalName>${project.artifactId}-${project.version}-staging</buildFinalName>
    </properties>
  </profile>
  <profile>
    <id>prod</id>
    <properties>
      <resource.directory>${basedir}/configs/prod/resources</resource.directory>
      <buildFinalName>${project.artifactId}-${project.version}</buildFinalName>
    </properties>
    </profile>
</profiles>
・・・

mvnコマンドで、PackageやInstallフェーズを実行時に、-PオプションでprofileのIDを指定すると対象のresourceでjarファイルが作成されます。
上記の設定の場合、-P prodなら本番環境用のxxx-env.jar、-P stagingなら検証環境用のxxx-env-staging.jar、何も指定しない(デフォルト)は開発用のxxx-env-dev.jarが実行されます。

3. Webモジュールに環境設定ファイルのpathを通す

Tomcat7のディレクトリopt/environment/appにxxx-env.jarを置き、webappsのモジュールから参照できるようにします。
今回はWebモジュールのsrc/main/webapp/META-INF/context.xmlに、VirtualWebappLoaderを設定し、WebモジュールのClasspathにxxx-env.jarを含めるようにします。

src/main/webapp/META-INF/context.xml
<?xml version='1.0' encoding='utf-8'?>
<Context>
  <Loader className="org.apache.catalina.loader.VirtualWebappLoader" virtualClasspath="/opt/environment/logtime/prod/*.jar"/>
  <JarScanner scanAllDirectories="true"/>
</Context>

maven-war-pluginを実行してcontext.xmlをWARファイルに含めるように設定します。

pom.xml(web)
・・・
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-war-plugin</artifactId>
  <version>2.5</version>
  <configuration>
    <containerConfigXML>src/main/webapp/META-INF/context.xml</containerConfigXML>
  </configuration>
</plugin>
・・・

4. webモジュールをTomcatにデプロイする

環境設定を排除したWARファイルを作成し、Tomcatにデプロイします。
dependencyからxxxx-envを削除し、profilesでWAR作成時はxxxx-envを含めないように設定します。

pom.xml(Web)
・・・
<profiles>
  <profile>
    <id>local</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <dependencies>
      <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>xxxx-env</artifactId>
    <version>0.0.1-SNAPSHOT</version>
      </dependency>
    </dependencies>
  </profile>
  <profile>
    <id>warpack</id>
  </profile>
</profiles>
・・・

上記により、'-P warpack'を指定した時だけ、xxx-envから依存性を排除します。
つまり、mvn -P warpack clean packageとすると、xxx-env.jarが含まれないWARが作成されます。
※デフォルトでは、xxx-envへの依存性が定義されているので開発時などIDEで実行するときは参照します。

作成したWARをTomcatのwebappsに配備します。

動作確認とまとめ

Tomcatを起動しWebアプリケーションにアクセスすると、本番環境用のDBへアクセスすることが確認できました。
opt/environment/appのjarを-P stagingで作成した、検証環境用のxxx-env-staging.jarに置き換え、Tomcatを再起動すると今度は検証環境用のDBにアクセスすることが確認できました。

こうすることで、例えば検証用と本番用でWARファイルが使いまわせるため、モジュールの同一性が保証でき、リリース間違いが減らせるようになります。

参考

Terasoluna 3.5. 開発プロジェクトのビルド
War ファイルにコンテキスト固有の情報を設定する
Apache Maven WAR Plugin
[Maven] Maven2 で Apache Tomcat の context.xml を WAR に追加する方法
コンテキスト情報の記述場所

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7