2

スクリプトには、OS X で最新の Java ランタイムを自動的に検出する関数がありbuild.sbtます。これは、いくつかの更新 (sbt または Scala) が気に入らなくなるまではうまくいきました。できませんsbt cleanが、エラーが発生します(以下)。

関数は次のとおりです(これを単に貼り付けてbuild.sbt実行sbt cleanするだけで、これをテストできます-コードを実行する必要はありません):

javaHome := {
  var s = System.getenv("JAVA_HOME")
  if (s==null) {
    // Try to detect the latest JDK
    //
    // OS X: "/Library/Java/JavaVirtualMachines/jdk1.xxx.jdk/Contents/Home" with greatest id (i.e. "7.0_11")
    // Linux: tbd
    // Windows: tbd
    //
    val base= new File("/Library/Java/JavaVirtualMachines")
    assert( base.isDirectory, "Java JDKs not found at: "+ base )
    //
    // Get the latest version number available
    //
    // Note: JDK 7 has i.e. "jdk1.7.0_11.jdk"
    //       JDK 8 (early access) has "jdk1.8.0.jdk" (no underscore)
    //
    // For re explanation, see: http://stackoverflow.com/questions/8213837/optional-grouping-in-scala-regular-expressions
    // Triple quotes """ means '\' does not need to be escaped.
    //
    val re = """^jdk(\d+)\.(\d+)\.(\d+)(?:_([\d]*))?\.jdk$""".r
    var best = 0  // latest version so far
    base.listFiles.filter(_.isDirectory).map( (f: File) => {    // 'dir.name' i.e. "jdk1.7.0_11.jdk", "jdk1.8.0.jdk"
      try {
        val re(a,b,c,d) = f.name    // unapplies the caught parts
        val abcd= (((a.toInt)*100 + b.toInt)*100 + c.toInt)*100 + (Option(d) getOrElse "0").toInt
        println( "Found JVM: ", a, b, c, d )
        if (b=="8") {
          throw new RuntimeException( "Cannot use JavaFX 8 due to ScalaFX: please set 'JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.xxx.jdk/Contents/Home' env.var." )
        } else if (abcd>best) {
          best= abcd
          s= base+"/"+f.name+"/Contents/Home/"   // postfix in OS X
        }
      } catch { 
        // not really supposed to be having non-matching directories there (just skip them)
        case e: MatchError => None
      }
    } )
    //
    if (s==null) {
      throw new RuntimeException( "No JDK found at: "+ base )
    }
  }
  //
  println( "*** Using Java JDK: "+ s )
  val dir = new File(s)
  if (!dir.isDirectory) {
    throw new RuntimeException( "No JDK found at: "+ s )
  }
  //
  Some(dir)  // 'sbt' 'javaHome' value is ': Option[java.io.File]'
}

これを実行するのは次のとおりです。

$ sbt clean
[info] Loading project definition from /Users/asko/Hg/ScalaSim/project
**error: symbol value re does not exist in $cdeec6b653504a14ad9f.$sbtdef**
[error] scala.reflect.internal.FatalError: 
[error]      while compiling: /Users/asko/Hg/ScalaSim/build.sbt
[error]         during phase: icode
[error]      library version: version 2.10.2
[error]     compiler version: version 2.10.2
[error]   reconstructed args: -classpath /Users/asko/Hg/ScalaSim/project/target/scala-2.10/sbt-0.13/classes:/Users/asko/.ivy2/cache/scala_2.10/sbt_0.13/com.github.retronym/sbt-onejar/jars/sbt-onejar-0.8.jar:/Users/asko/.ivy2/cache/scala_2.10/sbt_0.13/com.eed3si9n/sbt-assembly/jars/sbt-assembly-0.9.1.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/actions-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/api-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/apply-macro-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/cache-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/classfile-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/classpath-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/collections-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/command-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/compile-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/compiler-integration-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/compiler-ivy-integration-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/completion-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/control-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/cross-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/incremental-compiler-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/io-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/ivy-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/ivy-2.3.0-rc1.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/jline-2.11.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/jsch-0.1.46.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/launcher-interface-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/logging-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/main-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/main-settings-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/persist-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/process-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/relation-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/run-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/sbinary_2.10-0.4.2.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/sbt-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/scala-reflect-2.10.2.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/task-system-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/tasks-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/test-agent-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/test-interface-1.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/testing-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/tracking-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/org.scala-sbt/sbt/0.13.0/xsbti/interface-0.13.0.jar:/Users/asko/.sbt/boot/scala-2.10.2/lib/jansi.jar:/Users/asko/.sbt/boot/scala-2.10.2/lib/jline.jar:/Users/asko/.sbt/boot/scala-2.10.2/lib/scala-compiler.jar:/Users/asko/.sbt/boot/scala-2.10.2/lib/scala-library.jar:/Users/asko/.sbt/boot/scala-2.10.2/lib/scala-reflect.jar:/Users/asko/Hg/ScalaSim/project/target/config-classes
[error] 
[error]   last tree to typer: Ident(re$1)
[error]               symbol: value re$1 (flags: <param> <synthetic> <triedcooking>)
[error]    symbol definition: re$1: util.matching.Regex
[error]                  tpe: util.matching.Regex
[error]        symbol owners: value re$1 -> constructor $cdeec6b653504a14ad9f$$anonfun$$sbtdef$1 -> anonymous class sbtdef$1 -> package <empty>
[error]       context owners: anonymous class sbtdef$1 -> package <empty>
[error] 
[error] == Enclosing template or block ==
[error] 
...
[error] 
[error] == Expanded type of tree ==
[error] 
[error] TypeRef(TypeSymbol(class Regex extends Serializable))
[error] 
[error] symbol value re does not exist in $cdeec6b653504a14ad9f.$sbtdef
[error] Use 'last' for the full log.
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? 

ここで何が起こっているのか誰か教えてもらえますか? それは私ですか、それともsbtですか?

4

2 に答える 2

2

sbt 0.13 のマクロ処理 (またはマクロ全般) にバグがあると思います。val re取り出すとうまくいきます:

val re = """^jdk(\d+)\.(\d+)\.(\d+)(?:_([\d]*))?\.jdk$""".r

javaHome := {
  var s = System.getenv("JAVA_HOME")
  if (s==null) {
    // Try to detect the latest JDK
    //
    // OS X: "/Library/Java/JavaVirtualMachines/jdk1.xxx.jdk/Contents/Home" with greatest id (i.e. "7.0_11")
    // Linux: tbd
    // Windows: tbd
    //
    val base= new File("/Library/Java/JavaVirtualMachines")
    assert( base.isDirectory, "Java JDKs not found at: "+ base )
    //
    // Get the latest version number available
    //
    // Note: JDK 7 has i.e. "jdk1.7.0_11.jdk"
    //       JDK 8 (early access) has "jdk1.8.0.jdk" (no underscore)
    //
    // For re explanation, see: http://stackoverflow.com/questions/8213837/optional-grouping-in-scala-regular-expressions
    // Triple quotes """ means '\' does not need to be escaped.
    //
    var best = 0  // latest version so far
    base.listFiles.filter(_.isDirectory).map( (f: File) => {    // 'dir.name' i.e. "jdk1.7.0_11.jdk", "jdk1.8.0.jdk"
      try {
        val re(a,b,c,d) = f.name    // unapplies the caught parts
        val abcd= (((a.toInt)*100 + b.toInt)*100 + c.toInt)*100 + (Option(d) getOrElse "0").toInt
        println( "Found JVM: ", a, b, c, d )
        if (b=="8") {
          throw new RuntimeException( "Cannot use JavaFX 8 due to ScalaFX: please set 'JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.xxx.jdk/Contents/Home' env.var." )
        } else if (abcd>best) {
          best= abcd
          s= base+"/"+f.name+"/Contents/Home/"   // postfix in OS X
        }
      } catch { 
        // not really supposed to be having non-matching directories there (just skip them)
        case e: MatchError => None
      }
    } )
    //
    if (s==null) {
      throw new RuntimeException( "No JDK found at: "+ base )
    }
  }
  //
  println( "*** Using Java JDK: "+ s )
  val dir = new File(s)
  if (!dir.isDirectory) {
    throw new RuntimeException( "No JDK found at: "+ s )
  }
  //
  Some(dir)  // 'sbt' 'javaHome' value is ': Option[java.io.File]'
}

これが私が得たものです:

*** Using Java JDK: /Library/Java/Home/
于 2013-09-23T16:51:01.487 に答える
1

sbtです。

とても興味深い!SBT 0.13 はマクロの使用に移行したため、宣言を簡素化できますが、そのために機能しなくなったものに出くわしました。これを SBT のバグとして報告してください。

于 2013-09-23T16:49:58.990 に答える