2009-08-13 13 views
15

Per un progetto java vorrei unire tutti i vasi di terze parti da cui dipende nel vaso principale creato da Apache Ant, che sono già riuscito a fare.Ant: escludi file dal file jar unito

Il problema è che alcuni di questi file jar hanno i file di firma nelle loro directory-META-INF, quindi quando provo a eseguire il mio file jar, viene visualizzato il messaggio di errore "Invalid signature file digest for Manifest main attributes". Dopo aver eliminato manualmente i file di firma, l'errore è scomparso.

Ho provato a filtrare i file di firma nel mio ant-file con un excludes -attributo o un exclude -tag, ma nulla sembra avere alcun effetto.

Questa è la formica-task:

<target name="jar" description="Creates the jar file"> 
    <mkdir dir="${jar}"/> 
    <jar destfile="${jar}/${ant.project.name}.jar" level="9" filesetmanifest="mergewithoutmain"> 
    <zipgroupfileset dir="${lib}" includes="*.jar"/> 
    <zipfileset dir="${class}"/> 
    <manifest> 
     <attribute name="Main-Class" value="${mainclass}"/> 
    </manifest> 
    </jar> 
</target> 

Come posso filtrare i file dal vaso con conseguente questo ant-compito? Grazie per l'aiuto!

+0

vedi bug [zipgroupfileset dovrebbe sostenere una specifica modello nidificato] (https://bz.apache.org/bugzilla/show_bug.cgi?id=34403). –

risposta

8

In base alle mie conoscenze, non è possibile filtrare quando si utilizza <zipgroupfileset>: l'inclusione/esclusione utilizzata qui si applica alle cerniere da unire, non al contenuto al loro interno.

Se si dispone di un insieme noto di JAR da unire, è possibile utilizzare le singole voci zipset > per ciascuna di esse; questo approccio consente di utilizzare include/exclude per filtrare i contenuti dell'archivio di origine.

Un approccio alternativo è semplicemente decomprimere tutto in una posizione temporanea, rimuovere/modificare i bit indesiderati, quindi riavviare tutto il backup.

34

carej ha ragione. Ho cercato di farlo, unendo altri vasi nel mio jar di applicazione escludendo alcuni file, e non c'è modo di usare <zipgroupfileset> per questo.

mia soluzione è una variante del metodo unzip/clean-up/vaso: ho unire tutti i barattoli di libreria esterni in uno con <zipgroupfileset>, poi unirlo miei con <zipfileset> che fa permettere filtraggio. Nel mio caso funziona notevolmente più veloce ed è più pulito di decomprimere i file su disco:

<jar jarfile="${dist}/lib/external-libs.jar"> 
    <zipgroupfileset dir="lib/"> 
    <include name="**/*.jar"/> 
    </zipgroupfileset> 
</jar> 
<sleep seconds="1"/> 
<jar jarfile="${dist}/lib/historadar-${DSTAMP}.jar" manifest="Manifest.txt"> 
    <fileset dir="${build}" includes="**/*.*"/> 
    <zipfileset src="${dist}/lib/external-libs.jar"> 
    <exclude name="*"/> 
    </zipfileset> 
</jar> 

Il primo <jar> mette tutti i vasi che trova in lib/in esterno-libs.jar, poi mi rendono aspettare per un in secondo luogo per evitare di ricevere avvisi sui file con date di modifica in futuro, quindi unisco i miei file di classe dalla directory build/con il contenuto di external-libs.jar escludendo i file nella sua radice, che in questo caso erano file README e esempi.

Poi ho il mio file README che elenca tutte le informazioni necessarie su queste librerie ho includere nella mia applicazione, come ad esempio licenza, sito web, ecc

+0

grazie, questo è stato davvero utile! – tth

2

È possibile utilizzare il parametro exclude in zipfileset tag per rimuovere i contenuti da file JAR esterni uniti, come questo:

<jar jarfile="${dist}/lib/external-libs.jar"> 
    <zipgroupfileset dir="lib/" excludes="META-INF/**/*"> 
    <include name="**/*.jar"/> 
    </zipgroupfileset> 
</jar> 

Il file JAR risultante sarà senza segno.

2

La risposta di Alberto funziona bene ma richiede tempo per decomprimere & rezip l'archivio.Ho implementato un nuovo compito Ant per utilizzare built-in funzioni di filtraggio, che si traduce in esecuzione molto più veloce:

public class FilterZipTask extends Task { 

    private Zip zipTask; 

    private List<FileSet> groupfilesets = new ArrayList<FileSet>(); 

    private String excludes; 

    public void setExcludesInZips(String excludes) { 
    this.excludes = excludes; 
    } 

    public void addZipGroupFileset(FileSet set) { 
    groupfilesets.add(set); 
    } 

    public void addZip(Zip zipTask) { 
    this.zipTask = zipTask; 
    } 

    @Override 
    public void execute() throws BuildException { 
    for (FileSet fileset : groupfilesets) { 
     Iterator<FileResource> iterator = fileset.iterator(); 
     while (iterator.hasNext()) { 
     ZipFileSet zfs = new ZipFileSet(); 
     FileResource resource = iterator.next(); 
     zfs.setSrc(resource.getFile()); 
     zfs.setExcludes(excludes); 
     zipTask.addZipfileset(zfs); 
     } 
    } 
    zipTask.execute(); 
    } 
} 

e utilizzarlo nel file di configurazione come segue:

<taskdef name="filterzip" classname="FilterZipTask"/> 
<filterzip excludesInZips="META-INF/*.*"> 
    <zipgroupfileset dir="${deps.dir}" includes="*.jar" /> 
    <zip destfile="${destjar}" /> 
</filterzip> 
0

ero anche affrontando lo stesso problema . Ho cercato molto su Google e ho trovato qualcosa che funzionava per me. Un-jar si cancella il file jar. META-INF/.SF, META-INF/ .DSA file. Aggiustalo di nuovo ed eseguilo non dovrebbe mostrare il messaggio di errore.

causa dell'errore è spiegato qui: http://qe-cafe.blogspot.in/2010/06/invalid-signature-file-digest-for.html

0

hanno lottato con lo stesso problema per un paio d'ore, quindi abbiamo finito per scrivere una nuova attività estendendo l'esistente:

import java.util.HashSet; 
import java.util.Set; 
import java.util.StringTokenizer; 

import org.apache.tools.ant.taskdefs.Jar; 
import org.apache.tools.ant.types.ResourceCollection; 
import org.apache.tools.ant.types.ZipFileSet; 

public class CustomizedJarTask extends Jar { 

    protected Set<String> filters; 

    @Override 
    public void add(ResourceCollection resources) { 
     if (filters != null && resources instanceof ZipFileSet) { 
      ZipFileSet set = ZipFileSet.class.cast(resources); 
      for (String filter : filters) 
       set.createExclude().setName(filter); 
     } 
     super.add(resources); 
    } 

    public void setFilters(String patterns) { 
     StringTokenizer tokenizer = new StringTokenizer(patterns, ", ", false); 
     while (tokenizer.hasMoreTokens()) { 
      if (filters == null) 
       filters = new HashSet<>(); 
      filters.add(tokenizer.nextToken()); 
     } 
    } 

} 

Con il sopra, tutto quello che serve nel file build è:

<taskdef name="customized-jar" classname="CustomizedJarTask" classpath="${basedir}/bin/" /> 
<customized-jar jarfile="${directory.build}/external-libs.jar" duplicate="fail" filters="META-INF/**"> 
    <zipgroupfileset dir="${directory.libs}"> 
     <include name="**/*.jar" /> 
    </zipgroupfileset> 
</customized-jar>