如何在sbt中检测JavaFX运行时jar

时间:2013-01-02 14:25:05

标签: scala javafx-2 sbt

我想要做的是在开头定义javaHome,从环境变量或固定字符串作为默认值。然后,我会使用那个字符串。

这是我尝试过的:

javaHome := Some(file("/Library/Java/JavaVirtualMachines/jdk1.7.0_10.jdk/Contents/Home"))

以后

unmanagedJars in Compile <+= (javaHome) { fn => Attributed.blank( fn + "/jre/lib/jfxrt.jar") }

我试过阅读[参考] [1]但它确实比Scala本身更复杂。请帮忙。

我可以通过在构建文件中间使用固定字符串来绕过这一点,但通常我不喜欢这样。

平台是OS X,sbt 0.12.1,JDK 7u10,Scala 2.9.2

修改 由于我找到了一个解决方案,我已经删除了错误消息和另外两个(不成功)尝试,因为它们只会混淆。

2 个答案:

答案 0 :(得分:5)

终于完成了这件事。似乎问题部分在于理解sbt值模型(以及纯粹过度使用自定义运算符!),部分是为了与sbt中使用的类型达成一致。

我会相应地编辑问题,但这是我的发现(和解决方案)。

  1. sbt值是预先打坐的。它们不是我无法设置myOwn的变量。 javaHome是sbt的已知值(或实际上是一个任务?)。

  2. 话虽如此,我想知道为什么sbt不能为我找到合适的JDK做得很好。哦,好吧。

  3. 提示:使用val xxx: Nothing = expression是一个伟大的工具,可用于查找各种类型的内容。一个人不能拥有类型为Nothing的实例,因此始终会失败,并会显示一条很好的错误消息,通知expression的(未知)类型。

    我的javaHome检测代码(来自build.sbt):

    //---
    // Note: Wouldn't 'sbt' be able to provide us a nice default for this (the following logic
    //      would deserve to be automatic, not in a project build script). AK 4-Jan-2013
    //
    javaHome := {
      var s = System.getenv("JAVA_HOME")
      if (s==null) {
        // tbd. try to detect JDK location on multiple platforms
        //
        // OS X: "/Library/Java/JavaVirtualMachines/jdk1.xxx.jdk/Contents/Home" with greatest id (i.e. "7.0_10")
        //
        s= "/Library/Java/JavaVirtualMachines/jdk1.7.0_10.jdk/Contents/Home"
      }
      //
      val dir = new File(s)
      if (!dir.exists) {
        throw new RuntimeException( "No JDK found - try setting 'JAVA_HOME'." )
      }
      //
      Some(dir)  // 'sbt' 'javaHome' value is ': Option[java.io.File]'
    }
    

    以下是使用它的片段(稍后在同一个文件中),确保我们可以访问jfxrt.jar(JavaFX 2.x运行时)。无论如何,Oracle(或sbt)应该将它放在类路径上,所以所有这些都可以省去。

    //---
    // JavaFX
    //
    // Note: We shouldn't even need to say this at all. Part of Java 7 RT (since 7u06) and should come from there (right)
    //      The downside is that now this also gets into the 'one-jar' .jar package (where it would not need to be,
    //      and takes 15MB of space - of the 17MB package!) AKa 1-Nov-2012
    //
    unmanagedJars in Compile <+= javaHome map { jh /*: Option[File]*/ =>
      val dir: File = jh.getOrElse(null)    // unSome
      //
      val jfxJar = new File(dir, "/jre/lib/jfxrt.jar")
      if (!jfxJar.exists) {
        throw new RuntimeException( "JavaFX not detected (needs Java runtime 7u06 or later): "+ jfxJar.getPath )  // '.getPath' = full filename
      }
      Attributed.blank(jfxJar)
    } 
    

    请注意,sbt不允许条目中的空行。为了避免这种情况,我使用了缩进的//行,我想要一些空格。

答案 1 :(得分:0)

<+=真的是要附加到“集合”设置,我认为它不支持字符串连接。 另外,在第二次尝试中,您都试图通过赋值运算符(<+=使用+运算符手动连接来连接,这肯定不是您想要的。只需将<+=替换为<<=,就应该让sbt满意。

unmanagedJars in Compile <<= javaHome map { jh => jh + "/jre/lib/jfxrt.jar" }

更新:原来我误读了你的帖子,完全错了。您使用<+=附加到unamanagedJar是正确的,并且使用+只是为了创建绝对文件路径。 对于那个很抱歉。 这次我实际上尝试用手头的sbt修复它,并设法让它编译。我实际上没有对一个真实的项目进行测试,我会让你尝试一下并报告它是否按预期工作。

unmanagedJars in Compile <+= javaHome map { jh => Attributed.blank( new File( jh.getOrElse(sys.error("Error, could not get java home")),"jre/lib/jfxrt.jar" ) ) }

这显然不是很好,但可能会有一些帮助使其更具可读性。