Javaのpropertyファイルと環境
propertyファイルには、環境に合わせて変わる値を設定する。
開発環境、検証環境、商用環境の3通りの環境があって、Antでビルドするときに環境にあった値が設定されるようにする方法は3通りほどある。
- 各環境用のpropertyファイルを用意して、
copy
タスクで対象の環境用のファイルをコピーする。 - 環境に合わせて変わる部分を変数にし、
replace
タスクで変換する。 - 環境に合わせて変わる部分を
replaceregexp
タスクによって正規表現で置換する。
各方法で共通の部分
各方法の説明に移る前に、各方法で共通の部分があるため先に記載する。
<target name="checktarget">
<fail message="target property is invalid:${target} ${line.separator}set the parameter product|staging|dev${line.separator}ex) ant -Dtarget=product deploy">
<condition>
<not>
<or>
<equals arg1="${target}" arg2="product" />
<equals arg1="${target}" arg2="staging" />
<equals arg1="${target}" arg2="dev" />
</or>
</not>
</condition>
</fail>
<condition property="env.product" value="true">
<equals arg1="${target}" arg2="product" />
</condition>
<condition property="env.staging" value="true">
<equals arg1="${target}" arg2="staging" />
</condition>
<condition property="env.dev" value="true">
<equals arg1="${target}" arg2="dev" />
</condition>
</target>
方法1
各環境用のpropertyファイルを用意して、copy
タスクで対象の環境用のファイルをコピーする。
<target name="src-compile" description="ソースファイルをコンパイルします">
<copy todir="${work.dir}" overwrite="yes">
<fileset dir="EnvironmentFile/${target}">
<include name="**" />
<exclude name="_*/**" />
</fileset>
</copy>
<javac 略>
</javac>
</target>
ディレクトリ構成は以下の通りとし、ant -Dtarget=staging
のように実行する。EnvironmentFile直下のディレクトリ名をtarget
プロパティと併せている。
※-Dtarget
:
-Dプロパティ名
でプロパティーを定義する。<property name="プロパティ名" value="値"/>
と同等。
/EnvironmentFile/dev/system.properties
/EnvironmentFile/staging/system.properties
/EnvironmentFile/product/system.properties
一番シンプルだが、プロパティファイルに変更があるたびに、環境分のファイルを修正しなければならず非効率。
方法2
環境に合わせて変わる部分を変数にし、replace
タスクで変換する。
<target name="dev-environment" if="env.dev">
<property name="db.pass" value="devPass" />
</target>
<target name="staging-environment" if="env.staging">
<property name="db.pass" value="stagingPass" />
</target>
<target name="production-environment" if="env.product">
<property name="db.pass" value="productPass" />
</target>
<target name="src-compile" description="ソースファイルをコンパイルします">
<replace file="${work.dir}/system.properties" token="@db-pass@" value="${db.pass}" encoding="UTF-8" />
<javac 略>
</javac>
</target>
@変数名@
のような命名ルールを策定する。replace
タスクのtoken
に変数を設定して以下のsystem.propertiesファイルを置換する。
dbPass=@db-pass@
この方式だと、プロパティファイルはどれだけ環境が増えても1つで済む。設定値が変わっても修正するファイルはbuild.xmlのみ。
しかしプロパティファイルに設定されているのが変数なので、自PCでEclipseから実行したいときなど、値に実際の開発環境の値ではなく変数名が設定されてしまう。
3つの方法で1と2の欠点を解消する。
方法3
環境に合わせて変わる部分をreplaceregexp
タスクによって正規表現で置換する。
2のreplace
タスクを以下の通りreplaceregexp
タスクに変更する。
<replaceregexp file="${work.dir}/system.properties" match="(dbPass=).*" byline="true" replace="\1${db.pass}" encoding="UTF-8" />
(dbPass=)
でdbPass=
をグループ化してreplace
部で後方参照できるようにし、実際の値部分は${db.pass}
で置換する。
system.propertiesファイルは毎回置換されるので、実際の開発環境の値を自PCのファイルに書いて問題ない。
dbPass=devPass
replaceregexp
のオプションはantのJavadocを参照のこと。
Attribute Description Required file file for which the regular expression should be replaced. Yes if no nested <fileset>
is usedmatch The regular expression pattern to match in the file(s) Yes, if no nested <regexp>
is usedreplace The substitution pattern to place in the file(s) in place of the regular expression. Yes, if no nested <substitution>
is usedflags The flags to use when matching the regular expression. For more information, consult the Perl5 syntax
g : Global replacement. Replace all occurrences found
i : Case Insensitive. Do not consider case in the match
m : Multiline. Treat the string as multiple lines of input, using "^" and "$" as the start or end of any line, respectively, rather than start or end of string.
s : Singleline. Treat the string as a single line of input, using "." to match any character, including a newline, which normally, it would not match.No byline Process the file(s) one line at a time, executing the replacement on one line at a time (true/false). This is useful if you want to only replace the first occurrence of a regular expression on each line, which is not easy to do when processing the file as a whole.
Defaults to false.No encoding The encoding of the file. since Apache Ant 1.6 No - defaults to default JVM encoding preserveLastModified Keep the file timestamp(s) even if the file(s) is(are) modified. since Ant 1.8.0. No, defaults to false