5

我有兴趣构建未压缩的 jar 文件,以便在只有少数类更改时使我的 rsync 更快,到目前为止,我不知道如何告诉sbtassembly禁用压缩。

server > inspect assembly
[info] Task: java.io.File
[info] Description:
[info]  Builds a single-file deployable jar.
[info] Provided by:
[info]  {file:/.../}server/*:assembly
[info] Dependencies:
[info]  server/*:assembly-merge-strategy(for assembly)
[info]  server/*:assembly-output-path(for assembly)
[info]  server/*:package-options(for assembly)
[info]  server/*:assembly-assembled-mappings(for assembly)
[info]  server/*:cache-directory
[info]  server/*:test(for assembly)
[info]  server/*:streams(for assembly)
[info] Delegates:
[info]  server/*:assembly
[info]  {.}/*:assembly
[info]  */*:assembly

...

server > inspect assembly-option(for assembly)
[info] Setting: sbtassembly.AssemblyOption = AssemblyOption(true,true,true,<function1>)
[info] Description:
[info]  
[info] Provided by:
[info]  {file:/.../}server/*:assembly-option(for assembly)
[info] Dependencies:
[info]  server/*:assembly-assemble-artifact(for package-bin)
[info]  server/*:assembly-assemble-artifact(for assembly-package-scala)
[info]  server/*:assembly-assemble-artifact(for assembly-package-dependency)
[info]  server/*:assembly-excluded-files(for assembly)
...

然而, AssemblyOption没有说明任何关于打包的内容,并且该插件似乎为此使用了 sbt 自己的Package,所以也许有一种方法可以配置?包依次调用IO.jar(...)来写入文件。这使用withZipOutput来制作一个 ZipOutputStream (或一个 JarOutputStream),我想在其上调用setMethod(ZipOutputStream.STORED),但我不能。

除了 sbt 功能请求之外还有什么想法吗?

4

1 回答 1

4

无法通过 sbt 配置直接执行此操作,因为 sbt 假定 zip 和 jar 工件中的任何文件都应该被压缩。

一种解决方法是解压缩并重新压缩(不压缩)jar 文件。您可以通过将以下设置添加到您的项目(例如在build.sbt中)来做到这一点:

packageBin in Compile <<= packageBin in Compile map { file =>
  println("(Re)packaging with zero compression...")
  import java.io.{FileInputStream,FileOutputStream,ByteArrayOutputStream}
  import java.util.zip.{CRC32,ZipEntry,ZipInputStream,ZipOutputStream}
  val zis = new ZipInputStream(new FileInputStream(file))
  val tmp = new File(file.getAbsolutePath + "_decompressed")
  val zos = new ZipOutputStream(new FileOutputStream(tmp))
  zos.setMethod(ZipOutputStream.STORED)
  Iterator.continually(zis.getNextEntry).
    takeWhile(ze => ze != null).
    foreach { ze =>
      val baos = new ByteArrayOutputStream
      Iterator.continually(zis.read()).
        takeWhile(-1 !=).
        foreach(baos.write)
      val bytes = baos.toByteArray
      ze.setMethod(ZipEntry.STORED)
      ze.setSize(baos.size)
      ze.setCompressedSize(baos.size)
      val crc = new CRC32
      crc.update(bytes)
      ze.setCrc(crc.getValue)
      zos.putNextEntry(ze)
      zos.write(bytes)
      zos.closeEntry
      zis.closeEntry
    } 
  zos.close
  zis.close
  tmp.renameTo(file)
  file
}

现在,当您package在 sbt 中运行时,最终的 jar 文件将被解压缩,您可以使用unzip -vl path/to/package.jar.

于 2013-08-16T21:35:40.250 回答