scala.io.Source.fromURI is broken

Scala で雑にファイルを読みたい時にたまに scala.io.Source を使いたくなる時があるかと思いますが、scala.io.Source.fromURI の使い方には注意が必要という話です。 そもそも scala.io は read しか機能が提供されていない謎の標準ライブラリなので java.nio.file.Files を使いましょうで終わる話ではありますが、あれはあれで雑にやりたい時は Scala との type conversion が面倒ってのがありまして。

まぁさておき、scala.io.Source.fromURI は引数として URI を受け付けるにも関わらず、なぜか URI が file scheme でない限り例外を投げてきます。

例えば、以下のようなコードがあったとして、

package example

import java.net.URI

object Hello extends App {
  println(scala.io.Source.fromURI(URI.create("https://www.google.com")))
}

このコードを実行すると以下の結果になります。

> run
[error] (run-main-0) java.lang.IllegalArgumentException: URI scheme is not "file"
java.lang.IllegalArgumentException: URI scheme is not "file"
        at java.io.File.<init>(File.java:421)
        at scala.io.Source$.fromURI(Source.scala:121)
        at example.Hello$.delayedEndpoint$example$Hello$1(Hello.scala:6)
        at example.Hello$delayedInit$body.apply(Hello.scala:5)
        at scala.Function0.apply$mcV$sp(Function0.scala:34)
        at scala.Function0.apply$mcV$sp$(Function0.scala:34)
        at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
        at scala.App.$anonfun$main$1$adapted(App.scala:76)
        at scala.collection.immutable.List.foreach(List.scala:389)
        at scala.App.main(App.scala:76)
        at scala.App.main$(App.scala:74)
        at example.Hello$.main(Hello.scala:5)
        at example.Hello.main(Hello.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
[trace] Stack trace suppressed: run last compile:run for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
        at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) Nonzero exit code: 1

結構謎いのが、scala.io には scala.io.Source.fromURL というメソッドも定義されていて、URL から読み込たい時はこちらを使うわけですが、普通に考えて、scala.io.Source.fromURL があるんだから scala.io.Source.fromURI に http/https scheme を与えた時はそっちの実装を使ってくれよって気持ちにしかなりません。

残念ですね。終わり。

Comments

comments powered by Disqus