Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make sbt-native-packager refrain from putting my resources into a jar file?

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.

like image 732
Adam Mackler Avatar asked Aug 28 '14 23:08

Adam Mackler


1 Answers

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.

like image 193
Moritz Avatar answered Nov 02 '22 22:11

Moritz