解決する問題はタイトル通りです。通常のJavaプログラムではリソースファイルはsrc/main/resources 以下に置かれ、ビルド時にこれらのリソースファイルがJARに組み込まれます。
しかし、これらのリソースファイルをJARの内部ではなく、外部フォルダに置きたいケースがあります。例えば、プロパティファイルをJARの外部に置くことで、DB接続情報のような環境依存の設定が変更された場合でも、ビルド無しにプログラムの動作を変えることができます。本記事では、Mavenを使用して、そのようなビルドを実現する方法を説明します。
外部リソースフォルダを指定する
maven-jar-pluginを使用して、src/main/resourcesに替わり、外部フォルダをclasspathに通すことでリソースを外部に置くことができます。以下ではJARファイルと同パスにあるsettingsフォルダを相対パス指定で設定するサンプルです。
前提条件として、JARファイルのインストール先フォルダ構成は次のようであるとします。
install_dir
L MY_JAR_FILE.jar
L settings
L my_resource.properties
pom.xmlに次のように記述します。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.gmail.greencoffeemaker.MainApp</mainClass>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<!-- フォルダ指定の場合、パスの最後に / をつけるのを忘れないこと -->
<Class-Path>./settings/</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugin>
</build>
JavaプログラムからはResoruceBundleクラスを使用して、特にパスを意識することなくリソースを扱うことができます。
ResourceBundle res = ResourceBundle.getBundle("my_resource");
String val = res.getString("mykey");
デバッグを簡単にする
上記の方法でリソースフォルダを外部に指定すると、Eclipseでデバッグ実行する際に実行構成で外部フォルダを設定しなくてはならず、面倒になります。
これを回避するため、リソースファイルはJavaの作法に則り、src/main/resources 以下に配置し、ビルド時にリソースファイルをtarget 以下に出力するようにビルド構成を変更します。このようにすることで、デバッグ実行時の煩わしさがなくなります。(デプロイはtarget以下のリソースファイルを使ってください)
リソースファイルの出力は、maven-antrun-pluginを使用して、antコマンドを実行することで行います。実行するコマンドは「出力先のディレクトリ作成」と「リソースファイルのコピー」の2つです。
前提条件として、プロジェクト構成は次のようであるとします。
my-project
L src/main/java
L src/main/resource
L my_resource.properties
L target
pom.xmlに次のように記述します。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<!-- 中略 -->
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<configuration>
<target>
<!-- コピー: /src/main/resources => /target/settings -->
<mkdir dir="${project.build.directory}/settings" />
<copy todir="${project.build.directory}/settings">
<fileset dir="${project.basedir}/src/main/resources" />
</copy>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugin>
</build>
Mavenでビルドを行うと、target 以下にJARファイルが作成されると同時にsettingsフォルダが作られて、リソースファイルがコピーされます。
$> mvn clean package
my-project
L src/main/java
L src/main/resource
L my_resource.properties
L target
L MY_JAR_FILE.jar
L settings
L my_resource.properties
以上です。