如何使用sbtassembly在sbt中禁用jar压缩?

时间:2012-11-20 22:37:03

标签: sbt

我有兴趣构建未压缩的jar文件,以便在只有少数类更改时使我的rsync更快,到目前为止,我无法弄清楚如何告诉sbtassembly禁用压缩。 / p>

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功能请求之外的任何想法?

1 个答案:

答案 0 :(得分: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
}

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