如何用sbt docker插件复制资源文件

我正在运行一个使用docker的应用程序,该应用程序崩溃,因为我的应用程序无法访问位于src/main/resources文件夹中的文件。 在这里我的文件project/plugins.sbt

 addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.1.4") 

我的build.sbt文件:

 organization := """foo""" name := """bar""" version := "1.0" scalaVersion := "2.11.7" libraryDependencies ++= Seq( "org.apache.kafka" % "kafka_2.10" % "0.10.0.0", "org.scalatest" % "scalatest_2.11" % "3.0.0-M16-SNAP1", "org.scalaz" %% "scalaz-core" % "7.2.5", "com.typesafe.akka" %% "akka-actor" % "2.4.11", "com.typesafe.play" % "play-json_2.11" % "2.4.8", "com.typesafe.scala-logging" %% "scala-logging" % "3.1.0", "com.typesafe" % "config" % "1.3.0", "com.amazonaws" % "aws-java-sdk" % "1.11.8", "ch.qos.logback" % "logback-classic" % "1.1.7", "com.typesafe.akka" % "akka-testkit_2.11" % "2.4.12" ) // the default value in sbt is set to true parallelExecution in Test := false resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/conigtent/repositories/snapshots" dependencyOverrides ++= Set( "com.fasterxml.jackson.core" % "jackson-databind" % "2.4.4" ) resolvers ++= Seq( "Sonatype Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/", "Sonatype Releases" at "https://oss.sonatype.org/content/repositories/releases/" ) // http://www.scala-sbt.org/sbt-native-packager/formats/docker.html enablePlugins(DockerPlugin, JavaAppPackaging) // enablePlugins(JavaAppPackaging) packageName in Docker := "foo/bar" 

这里的主要文件:

 object FGS_MainApp extends LazyLogging { val actorSystemName = "SYS" println("Create actor sys " + actorSystemName) val system = ActorSystem(actorSystemName) private val t = new Thread { override def run() = { if (system != null) { Database.closeConnection system.terminate logger.info("ACTOR SYSTEM SHUTDOWN") } } } Runtime.getRuntime.addShutdownHook(t) def main(args : Array[String]) = { // TODO : this needs to be remove quickly val saslPath = getClass.getResource("/sasl.conf").getPath println("saslPath = " + saslPath) System.setProperty("java.security.auth.login.config", saslPath) } } 

然后当我运行命令: sbt docker:publishLocal && docker run -it foo/bar:1.0 ,我得到这个错误:

 Caused by: java.lang.SecurityException: java.io.IOException: Configuration Error: No such file or directory 

打印的path是:

 file:/opt/docker/lib/foo.bar-1.0.jar!/sasl.conf 

我在build.sbt的configuration错过了什么?

更新

 Caused by: org.apache.kafka.common.KafkaException: java.lang.SecurityException: java.io.IOException: Configuration Error: No such file or directory at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:86) at org.apache.kafka.common.network.ChannelBuilders.create(ChannelBuilders.java:70) at org.apache.kafka.clients.ClientUtils.createChannelBuilder(ClientUtils.java:83) at org.apache.kafka.clients.consumer.KafkaConsumer.<init>(KafkaConsumer.java:623) ... 18 more Caused by: java.lang.SecurityException: java.io.IOException: Configuration Error: No such file or directory at sun.security.provider.ConfigFile$Spi.<init>(ConfigFile.java:137) at sun.security.provider.ConfigFile.<init>(ConfigFile.java:102) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at java.lang.Class.newInstance(Class.java:442) at javax.security.auth.login.Configuration$2.run(Configuration.java:255) at javax.security.auth.login.Configuration$2.run(Configuration.java:247) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.login.Configuration.getConfiguration(Configuration.java:246) at org.apache.kafka.common.security.authenticator.AbstractLogin.login(AbstractLogin.java:61) at org.apache.kafka.common.security.authenticator.LoginManager.<init>(LoginManager.java:46) at org.apache.kafka.common.security.authenticator.LoginManager.acquireLoginManager(LoginManager.java:68) at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:78) ... 21 more Caused by: java.io.IOException: Configuration Error: No such file or directory at sun.security.provider.ConfigFile$Spi.init(ConfigFile.java:335) at sun.security.provider.ConfigFile$Spi.init(ConfigFile.java:271) at sun.security.provider.ConfigFile$Spi.<init>(ConfigFile.java:135) ... 35 more 

它显示了这一行:

private val kafkaConsumer = new KafkaConsumer[String, Array[Byte]](kafkaProps)其中, kafkaPropsjava.util.Propertiestypes。 所以它无法find资源文件夹中的文件。

你遇到的问题是如何处理src/main/resources 。 这是一个特殊的文件夹,其内容将包含在由sbt构build的jar文件中。 它从来没有真正被复制到一个文件到你的通用包中。 这就是为什么打印出来的文件path包括jar名称和! – 这意味着文件压缩的jar 里面 。 很明显,卡夫卡库不处理这个问题。

为了解决这个问题,你应该把文件放在不同的位置,比如src/main/conf (可选,但严格讲更准确),然后映射到你的通用包中:

 mappings.in(Universal) += ((sourceDirectory.value / "main" / "conf" / "sasl.conf"), "conf/sasl.conf")) 

这现在将作为通用包中的conf/sasl.conf文件提供。