実行可能JARの実行時ファイルパスを取得する

実行プログラムと同じ場所にある設定ファイルを読み取るために 実行プログラムのファイルパスを取得したいことありますよね。

Java の実行プログラム 実行可能 JAR ファイル の実行時ファイルパスを取得する方法を紹介します。

ProtectionDomain CodeSource

Java ではクラスのドメイン属性から そのクラスが読み込まれた位置を取得することができるようになっています。

Class インスタンスの getProtectionDomain() メソッドによって ProtectionDomain インスタンスを取得できます。

次に ProtectionDomain インスタンスの getCodeSource() メソッドによって CodeSource インスタンスを取得できます。

この CodeSource インスタンスは クラスの読み込み位置 URL を保持しています。CodeSource インスタンスの getLocation() メソッドによって はじめに指定した Class インスタンスを格納している JAR ファイルのパスを取得することができます。

実際のコードは以下のようになります。

Sample.java
package 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.MF
Main-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.jarC:¥temp JAR ファイルのあるフォルダー
  • C:¥temp¥sample.exeC:¥temp EXE ファイルのあるフォルダー
  • C:¥workspace¥sample¥binC:¥workspace¥sample プロジェクトのルートフォルダー

このフォルダーをプログラムの基準パスとして ここに設定ファイルなどを配置するように構成すると便利です。

この記事を共有しませんか?