実行プログラムと同じ場所にある設定ファイルを読み取るために、 実行プログラムのファイルパスを取得したいことありますよね。
Java の実行プログラム (実行可能 JAR ファイル) の実行時ファイルパスを取得する方法を紹介します。
ProtectionDomainとCodeSource
Java ではクラスのドメイン属性から、 そのクラスが読み込まれた位置を取得することができるようになっています。
Class
インスタンスの getProtectionDomain()
メソッドによって ProtectionDomain
インスタンスを取得できます。
次に、 ProtectionDomain
インスタンスの getCodeSource()
メソッドによって CodeSource
インスタンスを取得できます。
この CodeSource
インスタンスは、 クラスの読み込み位置 (URL) を保持しています。CodeSource
インスタンスの getLocation()
メソッドによって、 はじめに指定した Class
インスタンスを格納している JAR ファイルのパスを取得することができます。
実際のコードは以下のようになります。
Sample.javapackage com.example;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.CodeSource;
import java.security.ProtectionDomain;
public class Sample {
public static void main(String[] args) throws Exception {
Path path = getApplicationPath(Sample.class);
System.out.println("path=" + path);
}
public static Path getApplicationPath(Class<?> cls) throws URISyntaxException {
ProtectionDomain pd = cls.getProtectionDomain();
CodeSource cs = pd.getCodeSource();
URL location = cs.getLocation();
URI uri = location.toURI();
Path path = Paths.get(uri);
return path;
}
}
実行可能JARファイルを作成して動かしてみる
ソースコード com\example\Sample.java
をコンパイルしておきます。(C:\temp\src
にソースコードを置いています。)
コマンドプロンプトC:¥temp>javac src¥com¥example¥Sample.java
実行可能 JAR ファイルを作成するために、 メイン ・ クラスを指定したマニフェストファイルを用意します。(C:\temp\\MANIFEST.MF
に置きました。)
MANIFEST.MFMain-Class: com.example.Sample
jar
コマンドで実行可能 JAR ファイルを作成します。
コマンドプロンプトC:¥temp>jar cfm sample.jar MANIFEST.MF -C src .
これで、 実行可能な sample.jar
が出来上がります。
- ここまでの手順はコマンドラインを使わずに、 Eclipse などの IDE で実行可能 JAR ファイルを作成しても構いません。
sample.jar
を実行して出力を確認します。
コマンドプロンプトC:¥temp>java -jar sample.jar path=C:¥temp¥sample.jar
ちゃんと、 実行可能 JAR ファイルのパスが表示されていますね。
EXE化してもファイルパスを取得できます
この ProtectionDomain
を使って実行時ファイルパスを取得する方法は、 exewrap を使って JAR ファイルを EXE 化した場合でも正しく動作します。
コマンドプロンプトC:¥temp>exewrap sample.jar Architecture: x86 (32-bit) Target: Java 5.0 (1.5.0.0) sample.exe (32-bit) version 0.0.0.1 C:¥temp>sample.exe path=C:¥temp¥sample.exe
Eclipseから実行した場合は?
開発中は JAR や EXE にせずに開発環境から直接実行することが多いですよね。Eclipse から実行した場合に取得されるパスがどのようになるのか見てみましょう。
path=C:\workspace\sample\bin
このような出力結果になりました。sample
というのはプロジェクト名です。bin
はプロジェクトの既定の出力フォルダー (Default output folder) です。
Eclipse の場合はファイルパスではなくフォルダーパスになってしまうのは仕方ないですね。
1つ上のフォルダーを参照すると扱いやすくなる
取得した Path
の getParent()
メソッドを呼んで、 1 つ上のフォルダーを取得すると扱いやすいフォルダーパスになります。(JAR/EXE/Eclipse で条件分岐させることなく共通のコードで済みます。)
1 つ上のフォルダーを取得すると、 それぞれ以下のようになります。
C:\temp\sample.jar
→C:\temp
(JAR ファイルのあるフォルダー)C:\temp\sample.exe
→C:\temp
(EXE ファイルのあるフォルダー)C:\workspace\sample\bin
→C:\workspace\sample
(プロジェクトのルートフォルダー)
このフォルダーをプログラムの基準パスとして、 ここに設定ファイルなどを配置するように構成すると便利です。