2009-08-13 144 views
15

對於一個java項目,我想將它所依賴的所有第三方jar合併到由Apache Ant創建的主jar中,我已經設法完成該jar。Ant:從合併的jar文件中排除文件

問題是,其中一些jar文件在其META-INF目錄中有簽名文件,所以當我嘗試運行我的jar文件時,出現錯誤消息"Invalid signature file digest for Manifest main attributes"。在我手動刪除簽名文件後,錯誤消失了。

我試圖過濾我的螞蟻文件中的簽名文件,excludes-attribute或exclude-tag,但沒有任何效果。

這是螞蟻的任務:

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

我怎麼能在這個螞蟻任務的濾除產生的jar文件?謝謝你的幫助!

+0

參見錯誤[zipgroupfileset應該支持嵌套圖案規格](https://bz.apache.org/bugzilla/show_bug.cgi?id=34403)。 – 2015-12-23 03:05:50

回答

8

據我所知,當使用<zipgroupfileset>時,無法過濾:在那裏使用的include/excludes適用於要合併的zip,而不適用於它們中的內容。

如果你有一套知名的JAR合併,你可以使用單獨的<zipset>條目;這種方法允許使用include/exclude來過濾源存檔的內容。

另一種方法是簡單地將所有內容解壓縮到臨時位置,刪除/修改不需要的位,然後將所有內容壓縮備份。

34

carej是對的。我一直在試圖做到這一點,將其他罐子合併到我的應用程序jar包中,但不包含某些文件,並且無法使用<zipgroupfileset>

我的解決方案是unzip/clean-up/jar方法的變體:我首先將所有外部庫jar合併爲一個與<zipgroupfileset>,然後將它合併到我的<zipfileset>,它允許過濾。在我的情況下,它的工作原理明顯更快,比文件解壓縮到磁盤清潔:

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

第一<jar>將所有發現中的lib罐子/成外部libs.jar,然後我讓等待一個其次,爲了避免將來有修改日期的文件出現警告,我將build /目錄中的類文件與external-libs.jar的內容合併,除了其根目錄中的文件(本例中爲README文件和例子。

然後,我有我自己的README文件,列出需要有關這些庫包括我在我的應用程序,如許可,網站上的所有信息等

+0

謝謝,這真的很有幫助! – tth 2012-11-15 05:06:27

2

可以使用exclude參數zipfileset標籤從刪除內容合併外部JAR文件,如下所示:

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

生成的JAR文件將是無符號的。

2

Alberto的回答正常,但需要時間解壓&重新壓縮檔案。我實現了一個新的Ant任務使用內置過濾功能,這導致更快的執行:

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

而且在構建文件中使用它,如下所示:

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

已經掙扎了幾個小時了同樣的問題,所以最終通過延長現有寫一個新的任務:

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

} 

隨着以上,所有我需要在構建文件是:

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