Sbt Package Command Do Not Copy Resources

sbt, scala

Solution

The SBT convention for resources is to put them in `src/main/resources/`, not `src/main/scala/resources/`. Try moving your `resources` folder up one level. Its content should then be included, meaning that you will get `icons` and `indicator` folders inside the generated jar file (directly at the root level, not inside a `resources` folder).

If you put the resources in scala, I think it copies only the files that are compiled (i.e. `.class` files resulting from scala compilation).

If it doesn't solve your problem, can you post the lines of code you use to load the resource?

Problem

I am using sbt for a simple, small GUI projects that load icons from `src/main/scala/resources`. At first, everything works fine and I can `compile`. `package`, and `run`. The generated jar and class files all have the resource folder in it. Then I do the `clean` command. I re-run the `compile` and `package`, and suddently the application crashes. I check the generated jars and classes, and found out that the `resources` folder are not copied this time. Running the application now gives me the `NullPointerException` pointing to the line where I load the resource (icon). I didn't change the sbt build files or anything in the project. Just run `clean` and re-run `compile` and `package`. I don't know where to start looking for the problem. Where should I start looking? What am I doing wrong? EDIT (the minimal example) The project is a standard Scala template from typesafe's g8 (https://github.com/typesafehub/scala-sbt.g8). Here's my `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" ) ) ) } ``` It builds the code fine previously. Here's the project code directory structure: It works fine and output this directory inside the jar at first: And suddently, when I do a `clean` and `compile` command via the sbt console, it didn't copy the resource directory in the jar or in the class directory (inside target) anymore. I can't do anything to get the resource directory copied to target now, except by restoring previous version and compile it one more time. I restore the previous version via Windows' history backup. Is it clear enough? Anything I need to add? EDIT: After moving the files to `src/main/resources`, the compiled files now contains the resources. But now, I can't run it in eclipse. Here's my code: ``` 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) } } ``` The TLDR version is this, I guess: ``` getClass.getResource("/icons/icon.png") ``` which works if I call from `sbt console` command. Here's the result when I call the code from `sbt console`: ``` scala> getClass.getResource("/icons/icon.png") res0: java.net.URL = file:/project/path/target/scala-2.9.2/classes/icons/icon.png ``` which when runned gives the following exception: ``` 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 ``` EDIT 2: It works now. I just deleted the project from eclipse, re-run `sbt eclipse` and it magically works. Not sure why (maybe caching?).

Original source