7
votes

I'm using the sbt-native-packager plugin to generate a start script for my application, which is very convenient as this plugin generates the correct classpath specification with all my library dependencies. I am not distributing this applictaion, therefore I'm not packaging the entire thing into one tarball. I just use the lib directory generated by sbt-native-packager that contains all the jar-files on which my project depends, both third-party libraries as well as the jar-file that contains my own class and resource files.

In my project's src/main/resources directory I have files that I want to be able to edit without having to use sbt-native-packager to regenerate the entire installation, for example configuration files. This is difficult because those files are zipped up in the jar file with all my classes.

Question: how can I tell sbt-native-packager not to put my resource files into a jar-file, while still generating the start-script with the correct classpath for those resource files to be located and read by my application as they are now from within the jar file? If this means leaving all my class files out of a jar file that is fine, as long as the files from src/main/resources remain as files that I can change without re-invoking sbt stage and as long as the start-script works.

1
I believe that you are trying to achieve is the default behavior of sbt-start-script github.com/sbt/…Johnny Everson
@Jhonny Everson That may be, but it was the README for that project that led me to sbt-native-packager. The first thing it says (under a very large heading) is that it may be replaced by sbt-native-packager, which makes it sound as if it's a bad idea to adopt it now since the developer expects to stop maintaining it. It also describes sbt-native-packager as being "more general," which suggests that anything that plugin can do, sbt-native-packager can also do.Adam Mackler

1 Answers

1
votes

While it is possible to filter these resources I would suggest to put them into a different directory and add them to the classpath.

Modifying the start script generated by sbt-native-packager is a bit cumbersome as the class com.typesafe.sbt.packager.archetypes.JavaAppBashScript that is generating the classpath is prefixing all paths with $lib_dir/. The cleanest approach would probably be to provide your own implementation and use that to generate the bashScriptDefines.

A simpler but hacky way would be to just add the following lines to your build.sbt:

packageArchetype.java_server

// add your config files to the classpath for running inside sbt
unmanagedClasspath in Compile += Attributed.blank(sourceDirectory.value/"main"/"config")

// map all files in src/main/config to config in the packaged app
mappings in Universal ++= {
  val configDir = sourceDirectory.value/"main"/"config"
  for {
    file <- (configDir ** AllPassFilter).get
    relative <- file.relativeTo(configDir.getParentFile)
    mapping = file -> relative.getPath
  } yield mapping
}

scriptClasspath ~= (cp => "../config" +: cp)

This will prepend $lib_dir/../config to your start script's classpath. If your app has to run on Windows you will have to provide similar settings for the batScriptDefines.