StoryEdit 開発日誌

ウェブアプリ StoryEditを作ってましたが延期。普通のブログ。

邪バ

久々にはまった。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への参照ばっかりだし、ほんとにわかりにくすぎて時間ばかりとられる昨今。。。