2012-11-20 22 views
5

Sono interessato a creare file jar non compressi per rendere più veloce il mio rsync quando solo poche classi cambiano e finora non riesco a capire come dire a sbtassembly di disabilitare la compressione.Come posso disabilitare la compressione jar in sbt usando 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 non dice nulla di imballaggio, tuttavia, e il plugin sembra utilizzare sbt propria Package per questo, quindi forse c'è un modo per configurare che ? Il pacchetto, a sua volta, chiama IO.jar(...) per scrivere il file. Questo utilizza withZipOutput per creare uno ZipOutputStream (o un JarOutputStream), sul quale vorrei chiamare setMethod(ZipOutputStream.STORED), ma non posso.

Eventuali idee diverse da una richiesta di funzione sbt?

risposta

4

Non c'è modo di farlo direttamente tramite la configurazione di sbt, dato che sbt presuppone che tutti i file all'interno di risorse zip e jar debbano essere compressi.

Una soluzione alternativa consiste nel decomprimere e ricollegare (senza compressione) il file jar. È possibile farlo aggiungendo la seguente impostazione al progetto (ad esempio 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 
} 

Ora, quando si esegue package nel SBT, il file jar finale sarà compresso, che è possibile verificare con unzip -vl path/to/package.jar.

Problemi correlati