tags:

views:

1377

answers:

2

Hi there. For a java project I'd like to merge all third-party jars it depends on into the main jar created by Apache Ant, which I already managed to do.

The problem is that some of these jar-files have signature-files in their META-INF-directories, so when I try to run my jar-file, I get the error message "Invalid signature file digest for Manifest main attributes". After I delete the signature-files manually the error is gone.

I tried to filter the signature files out in my ant-file with an excludes-attribute or an exclude-tag, but nothing seems to have any effect.

This is the ant-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>

How can I filter files from the resulting jar in this ant-task? Thanks for your help!

+3  A: 

To the best of my knowledge there's no way to filter when using <zipgroupfileset>: the include/excludes used there apply to the zips to be merged, not the content within them.

If you have a well-known set of JARs to merge you could use individual <zipset> entries for each one; this approach allows using include/exclude to filter the contents of the source archive.

An alternative approach is to simply unzip everything into a temporary location, remove/modify the unwanted bits, then zip everything back up.

+3  A: 

carej is right. I've been trying to do this, merging other jars into my application jar excluding some files, and there is no way to use <zipgroupfileset> for it.

My solution is a variant of the unzip/clean-up/jar method: I first merge all the external library jars into one with <zipgroupfileset>, then merge it into mine with <zipfileset> which does allow filtering. In my case it works noticeably faster and is cleaner than unzipping the files to disk:

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

The first <jar> puts all the jars it finds in lib/ into external-libs.jar, then I make it wait for one second to avoid getting warnings about the files having modification dates in the future, then I merge my class files from the build/ directory with the content of external-libs.jar excluding the files in its root, which in this case were README files and examples.

Then I have my own README file that lists all information needed about those libraries I include in my application, such as license, website, etc.

Alberto González Palomo