2009-04-15 4 views
6

Sembra che la costruzione di un jar o zip dallo stesso identico file di origine produca sempre un file diverso. Ho provato questo usando sia il comando java jar, sia le attività jar e zip nel form.Differenza binaria nel file Zip/Jar

Sembra essere dovuto al fatto che i nuovi vasi/zip hanno il timestamp impostato sull'ora corrente su ciascun file memorizzato.

C'è un modo per forzare uno strumento zip a utilizzare semplicemente la data/ora sul file sul filesystem per garantire che un jar creato dalla stessa identica sorgente appaia esattamente lo stesso?

+0

Se stai cercando istruzioni passo passo per costruire un JAR deterministico (firma SHA1 ripetibile), ecco un articolo: http: //gary-rowe.com/agilestack/2013/08/08/how-to-create-a-deterministic-jar/ –

+0

JAR è un formato leggermente diverso da ZIP. JAR è basato su ZIP, ma include file manifest e firme, mentre ZIP non lo fa. – jww

risposta

1

Ok, un collaboratore e ho trovato una soluzione che funziona per noi.

Invece di reingegnerizzazione dell'intero nostro processo di generazione di non eliminare i file di classe o jar, abbiamo utilizzare questa procedura:

  1. costruire nuovi artefatti.
  2. Utilizzare jardiff (parte di jnlp) per confrontare le modifiche dalla build precedente.
  3. Se il vaso di diff che jardiff produce non ha cambiamenti, ottenere artefatti dalla build precedente.

Sì, so che suona kludgy, ma è certo che batte lo script di riscrittura per tenerne conto. Inoltre, possiamo creare una build completamente pulita su una macchina nuova (in caso di errore del server), e questo processo garantirà che vengano prodotti solo i jar effettivamente aggiornati.

1

Non penso che ci sia un modo per fare zip, ma si potrebbe certamente battere il timestamp sui file sul filesystem in una data conosciuta (usando il comando 'touch' sotto Unix - Non so cosa sotto Windows) prima di creare il barattolo.

+1

ci sono touch util disponibili su Windows. Ma questo non risolverà il problema, come ho capito. La domanda sembra dire che le voci all'interno della zip ottengano l'ora corrente, piuttosto che l'ora sul file. Il tocco non risolverà questo. – Cheeso

+0

No, il vero problema è che se si rigenera un file, anche se lo si genera con gli stessi contenuti, si ottiene un timestamp dell'MT dell'ultima rigenerazione, quindi se si chiude il file, poiché lo zip memorizza il mtime, sarà diverso anche se i contenuti sono gli stessi. – pjz

+0

Cheeso è corretto. Anche prendendo lo stesso identico file sorgente e costruendo un barattolo due volte, i timestamp all'interno del barattolo cambiano. –

1

Avevo un problema simile e, come suggerisce pjz, ho risolto il problema "toccando" i file prima di aggiungerli al contenitore (quindi, ha funzionato per me :-)). Puoi trovare il tocco per Windows, se necessario, in GNU Windows Utilities, core utils: http://gnuwin32.sourceforge.net/packages/coreutils.htm, ma è un grande pacchetto solo per questo singolo (anche se ci sono molte altre utilità utili che potrebbero piacerti), o in alternativa , scarica qualcosa come http://www.softpedia.com/progClean/Touch-for-Windows-Clean-41086.html.

+0

Ho provato prima questo, purtroppo, questo non funziona. Vedi il commento di Cheeso sopra. –

3

La differenza binaria è dovuta al timestamp dei file manifest. Se si consente a jar di creare un manifest stesso, verrà creato un manifest sul volo e verrà impostato il manifest creato su currentTimeMillis.

È possibile risolverlo da:
1. Non aggiunge un manifesto (se la vostra utilizzando formica è necessario utilizzare zip al posto del vaso)
2. Aggiungere il manifesto come si aggiungono file normali. (Quindi manifest è un file sul tuo filesystem e non è creato al volo)