4

我有一个带有一些 webjar 和常见 jar 依赖项的sbt-web项目。我想从我的 jar 依赖项之一获取资源文件并将其用于连接任务。但我不知道如何在我的 build.sbt 中引用依赖 jar 中的资源。

4

3 回答 3

8

我终于找到了这个文档的解决方案。主要思想是在类路径依赖项中找到正确的 jar,将其解压缩到临时文件夹并使用这些文件执行您需要的操作。在我的情况下,我将它复制到我的目标目录并在连接任务中使用它。

我最终得到以下代码:

def copyResourceFromJar(classpathEntry: Attributed[File], jarName: String, resourceName: String) = {
  classpathEntry.get(artifact.key) match {
    case Some(entryArtifact) => {
      // searching artifact
      if (entryArtifact.name.startsWith(jarName)) {
        // unpack artifact's jar to tmp directory
        val jarFile = classpathEntry.data
        IO.withTemporaryDirectory { tmpDir =>
          IO.unzip(jarFile, tmpDir)
          // copy to project's target directory
          // Instead of copying you can do any other stuff here 
          IO.copyFile(
            tmpDir / resourceName,
            (WebKeys.webJarsDirectory in Assets).value / resourceName
          )
        }
      }
    }
    case _ =>
  }
}
for(entry <- (dependencyClasspath in Compile).value) yield {
  copyResourceFromJar(entry, "firstJar", "firstFile.js")
  copyResourceFromJar(entry, "secondJar", "some/path/secondFile.js")
}

这段代码应该放在任务中。例如:

val copyResourcesFromJar = TaskKey[Unit]("copyResourcesFromJar", "Copy resources from jar dependencies")
copyResourcesFromJar := {
  //your task code here
}
copyResourcesFromJar <<= copyResourcesFromJar dependsOn (dependencyClasspath in Compile)

并且不要忘记将此任务作为依赖项添加到您的构建任务中。就我而言,它看起来像这样:

concat <<= concat dependsOn copyResourcesFromJar
于 2015-07-15T10:10:06.513 回答
0

通常getResourceAsStream有效:

getClass.getResourceAsStream("/path/to/resource/in/jar")

读取资源很重要,因为 Stream getClass.getResource不起作用。

于 2015-07-14T12:40:49.803 回答
0

我认为其他答案对我不起作用,因为它们使用的是旧版本的 SBT。我一直在努力解决这个问题,但我终于找到了工作。guardrail这是在 SBT v1.5.5 上的任意编译任务(我的是)之前执行此资源复制的完整脚本:

lazy val myDep = "my-dep-project"
lazy val myFilename = "someDir/myFile.yaml"

val copyResourcesFromJars =
  TaskKey[Unit]("copyResourcesFromJars", "Copy specific resources to be used by this project")

copyResourcesFromJars := {
  def copyResourceFromJar(classpathEntry: Attributed[File], jarName: String, resourceName: String): Unit = {
    classpathEntry.get(artifact.key) match {
      case Some(entryArtifact) =>
        // searching artifact
        if (entryArtifact.name.startsWith(jarName)) {
          // unpack artifact's jar to tmp directory
          val jarFile = classpathEntry.data
          IO.withTemporaryDirectory { tmpDir =>
            IO.unzip(jarFile, tmpDir)
            // copy to project's target directory
            // Instead of copying you can do any other stuff here
            IO.copyFile(
              tmpDir / resourceName,
              baseDirectory.value / s"target/$resourceName"
            )
          }
        }
      case _ =>
    }
  }

  (Compile / dependencyClasspath).value.foreach(entry =>
    copyResourceFromJar(entry, myDep, myFilename)
  )
}

Compile / guardrail := (Compile / guardrail dependsOn copyResourcesFromJars).value

(project in file(".")).settings(
  ...
  Compile / guardrailTasks := List(
    ScalaServer(
      baseDirectory.value / s"target/$myFilename",
      pkg = "my.pkg.guardrail"
    )
  )
)
于 2021-10-22T16:20:00.257 回答