I'm interested in building uncompressed jar files to make my rsync faster when only a few classes change and so far, i can't figure out how to tell sbtassembly to disable compression.
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 doesn't say anything about packaging, however, and the plugin seems to use sbt's own Package for that, so maybe there's a way to configure that? Package, in turn, calls IO.jar(...) to write the file. That uses withZipOutput to make a ZipOutputStream (or a JarOutputStream), on which i'd want to call setMethod(ZipOutputStream.STORED), but i can't.
Any ideas other than an sbt feature request?
There is no way to do this directly via sbt configuration, since sbt assumes that any files within zip and jar artifacts should be compressed.
One workaround is to unzip and re-zip (without compression) the jar file. You can do this by adding the following setting to your project (e.g. in 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
}
Now when you run package
in sbt, the final jar file will be uncompressed, which you can verify with unzip -vl path/to/package.jar
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With