邪バ
久々にはまった。workaroundはかけたが、意味がわかってないのでメモ。
以下のような、ファイルのパスをURLで受け付けるコードがあった。
private final static String DEFAULT_CONFIGURATION = "config.yaml"; private URL getConfigURL() throws ConfigurationException { String configUrl = System.getProperty("xxxx.config"); if (configUrl == null) configUrl = DEFAULT_CONFIGURATION; URL url; try { url = new URL(configUrl); url.openStream().close(); } catch (...) { ... } return url; }
IntelliJから実行すると、Exceptionがスローされてしまう。Debuggerからの実行だと、実行パスが異なるんだろうと思い、絶対パス指定を試みる。DEFAULT_CONFIGURATIONを絶対パスに書き換える。しかし、例外が投げられてしまう。
System.getProperty("user.dir")などで、実行パスを調べたり、いろいろ試してて、結局以下の方法に。
//private final static String DEFAULT_CONFIGURATION = "config.yaml"; private final static String DEFAULT_CONFIGURATION = "/home/hoge/xxxx/conf/config.yaml"; private URL getConfigURL() throws ConfigurationException { String configUrl = System.getProperty("xxxx.config"); if (configUrl == null) configUrl = DEFAULT_CONFIGURATION; URL url; try { File f = new File(configUrl); url = f.toURI().toURL(); url.openStream().close(); } catch (Exception e) { ... } return url; }
くそダサいので、toStringを使って、文字列を確認。'file:/'が先頭につくだけのようだ。このため、最終的に以下のように落ち着く。
private final static String DEFAULT_CONFIGURATION = "file:/home/hoge/xxxx/conf/config.yaml"; private URL getConfigURL() throws ConfigurationException { String configUrl = System.getProperty("xxxx.config"); if (configUrl == null) configUrl = DEFAULT_CONFIGURATION; URL url; try { url = new URL(configUrl); url.openStream().close(); } catch (Exception e) { ... } return url; }
これでうまく動く。
納得がいかないのは、絶対パスだと'file:'が必要で、もともとの表現だと、'file:'がついてなくてもファイルが読まれている点。これはなんでなのか、ドキュメントを読んでみてもいまいちわからぬ。
new URL(String)は、new URL(URL, String)の第一引数がNULLの場合と同じ、とある。んで、new URL(URL, String)はこちら。
http://docs.oracle.com/javase/jp/6/api/java/net/URL.html#URL(java.net.URL, java.lang.String)
うーむ。。。文字列がスラッシュではじまると、コンテキストが無視される、、、???
RFCへの参照ばっかりだし、ほんとにわかりにくすぎて時間ばかりとられる昨今。。。