Sbt包命令不复制资源

时间:2012-11-18 10:45:37

标签: scala sbt

我正在使用sbt来处理从src/main/scala/resources加载图标的简单小型GUI项目。起初,一切正常,我可以compilepackagerun。生成的jar和类文件都包含资源文件夹。然后我执行clean命令。我重新运行compilepackage,突然之间应用程序崩溃了。我检查生成的jar和类,发现这次没有复制resources文件夹。

现在运行应用程序会给我NullPointerException指向我加载资源的行(图标)。

我没有更改sbt构建文件或项目中的任何内容。只需运行clean并重新运行compilepackage即可。我不知道从哪里开始寻找问题。我该在哪里开始寻找?我做错了什么?

编辑(最小例子)

该项目是来自typesafe的g8(https://github.com/typesafehub/scala-sbt.g8)的标准Scala模板。这是我的Build.Scala

import sbt._
import sbt.Keys._

object ObdscanScalaBuild extends Build {
  val scalaVer = "2.9.2"

  lazy val obdscanScala = Project(
    id = "obdscan-scala",
    base = file("."),
    settings = Project.defaultSettings ++ Seq(
      name := "project name",
      organization := "thesis.bert",
      version := "0.1-SNAPSHOT",
      scalaVersion := scalaVer,
      // add other settings here

      // resolvers

      // dependencies
      libraryDependencies ++= Seq (
        "org.scala-lang" % "scala-swing" % scalaVer,
        "org.rxtx" % "rxtx" % "2.1.7"
      )
    )
  )
}

之前构建代码很好。这是项目代码目录结构:

enter image description here

它工作正常,首先在jar中输出这个目录:

enter image description here

突然之间,当我通过sbt控制台执行cleancompile命令时,它不再复制jar或类目录(目标内部)中的资源目录。我现在无法做任何事情来将资源目录复制到目标,除非恢复以前的版本并再次编译它。我通过Windows的历史记录备份恢复以前的版本。

足够清楚了吗?我需要添加什么?

修改

将文件移动到src/main/resources后,编译的文件现在包含资源。但现在,我无法在日食中运行它。这是我的代码:

object ControlPanelContent {
  val IconPath = "/icons/"
  val DefaultIcon = getClass.getResource(getIconPath("icon"))

  def getImage(name: String) = {
    getClass.getResource(getIconPath(name))
  }

  def getIconPath(name: String) = {
    IconPath + name + ".png"
  }
}

case class ControlPanelContent(title: String, iconName: String) extends FlowPanel {
  name = title
  val icon: ImageIcon = createIcon(iconName, 64)

  val pageTitle = new Label(title)

  protected def createIcon(name: String, size: Int): ImageIcon = {
    val path: Option[URL] = Option(ControlPanelContent.getImage(name))

    val img: java.awt.Image = path match {
      case Some(exists) => new ImageIcon(exists).getImage
      case _            => new ImageIcon(ControlPanelContent.DefaultIcon).getImage
    }
    val resizedImg = img.getScaledInstance(size, size, Image.SCALE_SMOOTH)
    new ImageIcon(resizedImg)
  }
}

TLDR版本就是这个,我想:

getClass.getResource("/icons/icon.png")

如果从sbt console命令调用,则有效。这是我从sbt console调用代码时的结果:

scala> getClass.getResource("/icons/icon.png")
res0: java.net.URL = file:/project/path/target/scala-2.9.2/classes/icons/icon.png

当运行时会出现以下异常:

Caused by: java.lang.NullPointerException
    at javax.swing.ImageIcon.<init>(Unknown Source)
    at thesis.bert.gui.ControlPanelContent.createIcon(ControlPanel.scala:54)
    at thesis.bert.gui.ControlPanelContent.<init>(ControlPanel.scala:33)
    at thesis.bert.gui.controls.DTC$.<init>(Diagnostics.scala:283)
    at thesis.bert.gui.controls.DTC$.<clinit>(Diagnostics.scala)
    ... 60 more

编辑2:现在可以使用了。我刚刚从eclipse中删除了该项目,重新运行sbt eclipse并且它神奇地起作用。不知道为什么(也许是缓存?)。

1 个答案:

答案 0 :(得分:7)

SBT资源惯例是将它们放在src/main/resources/中,而不是src/main/scala/resources/。尝试将resources文件夹向上移动一级。然后应该包含其内容,这意味着您将在生成的jar文件中(直接在根级别,而不是icons文件夹中)获得indicatorresources个文件夹。

如果您将资源放在scala中,我认为它只复制已编译的文件(即scala编译产生的.class文件)。

如果它无法解决您的问题,您可以发布用于加载资源的代码行吗?