2009-08-13 3 views
15

Für ein Java-Projekt möchte ich alle JAR-Dateien von Drittanbietern zusammenführen, von denen es abhängig ist, in das von Apache Ant erstellte Haupt-JAR, das ich bereits geschafft habe.Ant: Dateien aus der zusammengefügten JAR-Datei ausschließen

Das Problem ist, dass einige dieser JAR-Dateien Signatur-Dateien in ihren META-INF -Verzeichnissen haben. Wenn ich versuche, meine JAR-Datei auszuführen, erhalte ich die Fehlermeldung "Invalid signature file digest for Manifest main attributes". Nachdem ich die Signaturdateien manuell gelöscht habe, ist der Fehler verschwunden.

Ich habe versucht, die Signaturdateien in meiner Ant-Datei mit einem excludes -Attribut oder einem exclude -Tag zu filtern, aber nichts scheint irgendeinen Effekt zu haben.

Dies ist die Ameise-Aufgabe:

<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> 

Wie ich Dateien aus dem resultierenden Glas in dieser Ameise Aufgabe filtern? Danke für Ihre Hilfe!

+0

Siehe bug [zipgroupfileset eine verschachtelte Muster-Spezifikation unterstützen sollte] (https://bz.apache.org/bugzilla/show_bug.cgi?id=34403). –

Antwort

8

Nach bestem Wissen und Gewissen gibt es keine Möglichkeit zu filtern, wenn <zipgroupfileset> mit: der include/schließt verwendet dort die Reißverschlüsse gelten verschmolzen werden, nicht der Inhalt in ihnen.

Wenn Sie eine bekannte Gruppe von JARs zum Zusammenführen haben, können Sie einzelne <zipset> Einträge für jede verwenden; Dieser Ansatz ermöglicht die Verwendung von include/exclude zum Filtern des Inhalts des Quellarchivs.

Ein alternativer Ansatz besteht darin, einfach alles in einen temporären Speicherort zu entpacken, die unerwünschten Bits zu entfernen/zu ändern und dann alles wieder hochzuladen.

34

Sorgfalt ist richtig. Ich habe versucht, dies zu tun, andere Gläser in meine Anwendung Jar außer einigen Dateien zu verschmelzen, und es gibt keine Möglichkeit, <zipgroupfileset> dafür zu verwenden.

Meine Lösung ist eine Variante der unzip/clean-up/jar Methode: ich all externe Bibliothek Gläser in eine mit <zipgroupfileset> ersten verschmelzen, es dann in Mine mit <zipfileset> verschmelzen die Filterung nicht gestattet. In meinem Fall funktioniert es deutlich schneller und sauberer ist als die Dateien auf die Festplatte entpackt:

<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> 

Die erste <jar> alle Gläser bringt es in lib/in Außen libs.jar findet, dann warte ich es für eins machen, Zweitens, um Warnungen über die Dateien mit Änderungsdatum in der Zukunft zu vermeiden, füge ich meine Klassendateien aus dem Verzeichnis build/mit dem Inhalt von external-libs.jar zusammen, mit Ausnahme der Dateien in seinem Stamm, in diesem Fall README-Dateien und Beispiele.

Dann habe ich meine eigene Readme-Datei, die alle Informationen über diese Bibliotheken benötigt listet ich in meiner Anwendung enthalten, wie Lizenz, Website usw.

+0

danke, das war wirklich hilfreich! – tth

2

Sie den Tag exclude Parameter in zipfileset verwenden können Inhalte entfernen fusionierte externe JAR-Dateien wie folgt:

Die resultierende JAR-Datei wird unsigniert.

2

Albertos Antwort funktioniert gut, aber braucht Zeit, um das Archiv zu entpacken &.Ich implementierte eine neue Ant-Task integrierten Filterfunktionen zu verwenden, dass die Ergebnisse in viel schnellere Ausführung:

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(); 
    } 
} 

Und es in Build-Datei wie folgt verwenden:

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

mit dem gleichen Problem schon seit ein paar Stunden zu kämpfen, so endete eine neue Aufgabe zu schreiben, indem die bestehende Verlängerung:

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()); 
     } 
    } 

} 

Mit dem oben, alles, was ich in der Build-Datei benötigen, ist:

<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>