【问题标题】:Get resource file from dependency in sbt从 sbt 中的依赖项获取资源文件
【发布时间】:2015-10-03 01:56:50
【问题描述】:

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

【问题讨论】:

    标签: scala jar resources sbt sbt-web


    【解决方案1】:

    我终于用this docs 找到了解决方案。主要思想是在类路径依赖项中找到正确的 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
    

    【讨论】:

    • 我使用这个解决方案来获取父项目中的 liquibase 变更集。谢谢
    【解决方案2】:

    通常 getResourceAsStream 有效:

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

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

    【讨论】:

      【解决方案3】:

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

      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"
          )
        )
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-22
        • 2014-07-07
        • 1970-01-01
        • 1970-01-01
        • 2020-07-05
        • 2016-06-20
        • 1970-01-01
        相关资源
        最近更新 更多