やり方に少々怪しいところがあるのですが自分が使っている方法を紹介します・・・
Class#getResourceでパッケージ階層に存在する任意のリソースにアクセスできるのはご存知と思います。その際Class#getResourceはリソースの場所をURLで返しますね?
例えば、次のようなコードを実行してみますと
java
1package com.ksoh;
2public class Main {
3 public static void main(String[] args) {
4 URL url = Main.class.getResource("com/ksoh/Main.class";
5 System.out.println(url.toExternalForm());
6 }
7}
jarにパッケージングする前にIDEなどから実行するとIDEが生成したclass fileの場所に応じて以下のような雰囲気のパスになります。
file:/C:/myproject/out/production/myproject/com/ksoh/Main.class
これをjarにパッケージングして例えばC:\に置いて実行すると以下のようにschemeがjava独特のもの(=jar)になります。
jar:file:/C:/myproject.jar!/com/ksoh/Main.class
これ以降が「ナンチャッテ」な方法になりますが、このURLのString表現を加工し、先頭(scheme)が"jar:"の場合にschemeと後半のjarファイル以降の部分を取り去るとjarが存在するディレクトリーの場所のURL(URI)が求まります。
そういうわけで、次のようなメソッドを作っておくとIDEで実行した場合ならパッケージのトップのディレクトリー、jarで実行した場合にはjarが置かれたディレクトリーが求まります。そこにプロパティーファイルなどを置いておけばこのディレクトリー相対でアクセスできるというあんばいにできます。
java
1package com.ksoh;
2
3public class Main extends Application {
4 public static void main(String[] args) {
5 System.out.println(getBaseDir().getAbsolutePath());
6 }
7
8 private static File getBaseDir() {
9 // トップレベルのpubicクラスを使ってください。
10 Class<?> cls = Teratailor.class;
11 String resourceName = cls.getCanonicalName();
12 URL url = cls.getResource(resourceName);
13 String s = url.toExternalForm();
14 assert s.endsWith(resourceName);
15 s = s.substring(0, s.length() - resourceName.length());
16 System.out.println(s);
17 if (s.startsWith("jar:")) {
18 int i = s.lastIndexOf('/');
19 s = s.substring(4, i);
20 }
21 try {
22 return new File(new URI(s));
23 } catch (URISyntaxException e) {
24 throw new RuntimeException(e);
25 }
26 }
27}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/11/18 05:34
2017/11/18 13:36 編集