プロパティファイルを外に置きたい!

バッチなんかを作ってると、よく思いますよね。
ぼくもそうでした。
なので、調べてわかったことや感じたことをまとめてみます。

・「外に配置する」ということ


メリット

  • 固定値が変更になってもいちいちコンパイルせずに済む。

例えば…

APIの接続先が変更になるかもしれない!とか、
リトライの間隔を調節したい!とか、
コンパイルした後で固定値が変わる可能性があるときに便利ですね。


デメリット

  • jarファイルと扱いが別になるので、独自ルールが出来る。

例えば…

「jarファイルとpropertiesファイルは必ず一緒のディレクトリに配置しなきゃならない」
というのは、作った人以外知らないわけですよね。
プログラムエラー以外の人的エラーが起こる可能性がある、
ってことかなと思いました。

・とりあえずやってみる

僕の場合は固定値の変更をするたびに、
いちいちコンパイルしなおすっていうのが煩わしかったので、
プロパティファイルの外だしを試してみることにしました。


1.プロパティファイルの位置を認識させるには

参考記事:
JARファイルの外部に配置したプロパティファイルを読み込む - 2007-03-17 - sakihiroの日記

なるほど、jarファイルとして固める際、
カレントディレクトリをクラスパスに指定してあげれば良い、
ということですね。

私のプロジェクトではMavenを利用しているので、
Mavenでjarファイルを生成する際のクラスパスの指定方法について調べました。


2.Mavenでjarファイル外にクラスパスを設定するには
参考記事:
build - Maven - how can I add an arbitrary classpath entry to a jar? - Stack Overflow

[Class-Path]要素をmaven-jar-pluginの中に設定すれば良さそうですね。


3.実装

pom.xml

<!-- 省略 -->

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.4</version>
  <configuration>
    <archive>
      <manifest>
        <mainClass>jp.co.iida.testprogram.Main</mainClass>
        <addClasspath>true</addClasspath>
      </manifest>
      <manifestEntries>
        <Class-Path>./</Class-Path>
      </manifestEntries>
    </archive>
  </configuration>
</plugin>

<!-- 省略 -->


Main.java

public class Main
{
  public static void main( String[] args )
  {
    String key = "property.hello";
    ResourceBundle bundle = ResourceBundle.getBundle("batch"); 
    System.out.println(bundle.getString(key));
  }
}


batch.properties

property.hello = Hello, World


4.実行

実装が終わりましたので、実際にjarを生成して試してみたいと思います。


メニューバーから、
[Run(実行)] > [Run Configurations(実行構成)]を選択。
f:id:iidaapp:20141008155424p:plain


[Maven build]をダブルクリックし、必要な箇所に記入する。
f:id:iidaapp:20141008160257p:plain



[実行]ボタンを押下すれば、pom.xmlに設定されたフォルダにjarファイルが出来ていると思います!
後は生成したjarファイルとprioertiesファイルをサーバ内の同じディレクトリに配置し、
Javaコマンドから実行すると…

[root@hogehoge ~]# ls /var/tmp/test/
batch.properties  test.jar  test2.jar
[root@hogehoge ~]# cd /var/tmp/test/    
[root@hogehoge test]# java -jar testprogram.jar
Hello, World

やったーできたー!

Eclipseの場合

Eclipse上でプロジェクトをそのまま実行(デバッグ)しようとすると、以下のエラーが出てしまいました。

Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name batch, locale ja_JP
	at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1427)
	at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1250)
	at java.util.ResourceBundle.getBundle(ResourceBundle.java:705)
	at jp.co.iida.testprogram.Main.main(Main.java:14)


Eclipse上での実行時には、別途クラスパスを指定してあげないといけません。

1.実行ボタンの横の▼をクリックして、「実行の構成」を押下します。
f:id:iidaapp:20141007153832p:plain

2.「クラスパス」タブの中から「ユーザー・エントリー」を選択し、「拡張」ボタンを押下します。
f:id:iidaapp:20141007154729p:plain

3.「拡張オプション」ウインドウの「外部フォルダーを追加」を選択して、「OK」ボタンを押下します。
f:id:iidaapp:20141007155014p:plain

4.クラスパスに追加したいフォルダを選択し、「OK」ボタンを押下します。
f:id:iidaapp:20141007155402p:plain

5.選択したフォルダが追加され、実行時にクラスパスとして認識するようになります。
f:id:iidaapp:20141007155530p:plain


デバッグの場合も、「デバッグの構成」から上記と同じように設定すれば無事実行できました!
f:id:iidaapp:20141008171922p:plain

・まとめ

無事に実践までできました。

こういったプロパティファイルの外だしは、
これからも使うことがあると思うので、
忘れないでおきたいです。