我正在使用sbt来处理从src/main/scala/resources
加载图标的简单小型GUI项目。起初,一切正常,我可以compile
。 package
和run
。生成的jar和类文件都包含资源文件夹。然后我执行clean
命令。我重新运行compile
和package
,突然之间应用程序崩溃了。我检查生成的jar和类,发现这次没有复制resources
文件夹。
现在运行应用程序会给我NullPointerException
指向我加载资源的行(图标)。
我没有更改sbt构建文件或项目中的任何内容。只需运行clean
并重新运行compile
和package
即可。我不知道从哪里开始寻找问题。我该在哪里开始寻找?我做错了什么?
编辑(最小例子)
该项目是来自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"
)
)
)
}
之前构建代码很好。这是项目代码目录结构:
它工作正常,首先在jar中输出这个目录:
突然之间,当我通过sbt控制台执行clean
和compile
命令时,它不再复制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
并且它神奇地起作用。不知道为什么(也许是缓存?)。
答案 0 :(得分:7)
SBT资源惯例是将它们放在src/main/resources/
中,而不是src/main/scala/resources/
。尝试将resources
文件夹向上移动一级。然后应该包含其内容,这意味着您将在生成的jar文件中(直接在根级别,而不是icons
文件夹中)获得indicator
和resources
个文件夹。
如果您将资源放在scala中,我认为它只复制已编译的文件(即scala编译产生的.class
文件)。
如果它无法解决您的问题,您可以发布用于加载资源的代码行吗?