失敗
アプリケーション固有のプロパティファイルを読み込むメソッドを S2Unit4 でテストしようとしたところ、プロパティファイルが読み込めず、エラーになってしまいました。
プロパティファイルを Web アプリからもテストクラスからも読み込めるようにするには、どうすればよいのでしょうか?
環境
このレポートは、以下の環境について記述したものです。
| JDK | Java SE Development Kit 6 Update 16 |
| Seasar | S2Container 2.4.39 |
| JUnit | JUnit 4.4 |
原因
問題となったメソッドは Web アプリからプロパティファイルを読み込むことのみを考えて作られていました。 Web アプリと S2Unit4 では、プロパティファイルの配置場所が異なるので、読み込めないのは当然ですね。
解決策
Web アプリと S2Unit4 のどちらであるかを判定するフラグを用意します。 その値にしたがって、読み込むプロパティファイルのパスを変更することとします。
(1) Web アプリ用 app.dicon の編集
アプリケーション固有のプロパティファイル名を propName として定義します。 また、Web アプリであるため testFlg を false にします。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd"> <components> <include path="convention.dicon"/> <include path="aop.dicon"/> <include path="j2ee.dicon"/> <component name="propName">"myprop.properties"</component> <component name="testFlg">false</component> </components>
(2) S2Unit4 用 app.dicon の編集
S2Unit4 用であるため、testFlg を true にします。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd"> <components> <include path="convention.dicon"/> <include path="aop.dicon"/> <include path="j2ee.dicon"/> <component name="propName">"myprop.properties"</component> <component name="testFlg">true</component> </components>
(3) クラスの編集
(1) と (2) で定義した testFlg の値により、読み込むプロパティファイルのパスを変更させます。 なお、プロパティファイルのパスは以下の方法で取得できます。
- Web アプリにおけるプロパティファイルのパス
- javax.servlet.ServletContext#getRealPath メソッドの引数に、/WEB-INF/classes/<プロパティファイル名> を指定します。
- S2Unit4 におけるプロパティファイルのパス
- org.seasar.framework.util.FileUtil#getCanonicalPath メソッドの引数に、src/main/resources/<プロパティファイル名> を指定します。
package mysample;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import javax.annotation.Resource;
import javax.servlet.ServletContext;
import org.seasar.framework.util.FileUtil;
public final class MyProp {
@Resource
private ServletContext application;
// 固有の設定
private static Properties myProp;
// プロパティのファイル名 (app.dicon の propName)
@Resource(name = "propName")
private String propName;
// ユニットテストの実行中であるかを判定するフラグ (app.dicon の testFlg)
@Resource(name = "testFlg")
private boolean testFlg;
/**
* アプリケーション固有のプロパティファイルを読み込んで、何らかの処理をします。
*/
public void process() {
loadMyProp();
// 何らかの処理
}
/**
* アプリケーション固有のプロパティファイルを読み込みます。
*/
private synchronized void loadMyProp() {
String propFilePath = null;
if (testFlg) {
// S2Unit4 実行時のパスを取得
propFilePath = FileUtil.getCanonicalPath(
new File("src/main/resources/" + propName));
} else {
// Web アプリ実行時のパスを取得
propFilePath = application.getRealPath("/WEB-INF/classes/" + propName);
}
try {
myProp = loadProperties(propFilePath);
} catch (IOException e) {
// 省略
}
}
/**
* 指定されたプロパティファイルを読み込みます。
*
* @param propFilePath
* プロパティファイルのパス
* @return プロパティ
* @throws IOException
* 入出力例外が発生した場合
*/
private Properties loadProperties(final String propFilePath) throws IOException {
Properties result;
FileInputStream fis = null;
try {
fis = new FileInputStream(propFilePath);
result = new Properties();
result.load(fis);
} finally {
if (fis != null) {
fis.close();
}
}
return result;
}
}
以上で、Web アプリと S2Unit4 のどちらからでもプロパティファイルが読み込めるようになります。
