Seasar - Web アプリと S2Unit4 のどちらからでもプロパティファイルを読み込みませる

失敗

アプリケーション固有のプロパティファイルを読み込むメソッドを 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 にします。

[src/main/resources/app.dicon - 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 にします。

[src/test/resources/app.dicon - 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/<プロパティファイル名> を指定します。
[MyProp.java - Web アプリと S2Unit4 のどちらでもプロパティファイルを読み込ませる]
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 のどちらからでもプロパティファイルが読み込めるようになります。

コメント

コメント投稿
(非公開)
     « アイコン一覧 »
(必須)

作成日:2009/09/08
更新日:2009/09/08