Ant: исключить файлы из объединенного файла jar
Для проекта java я хотел бы объединить все сторонние банки, в зависимости от того, в чем он состоит, в основном банке, созданной Apache Ant, что я уже успел сделать.
Проблема в том, что некоторые из этих jar файлов имеют файлы-подписи в своих META-INF
-directories, поэтому, когда я пытаюсь запустить свой jar файл, я получаю сообщение об ошибке "Invalid signature file digest for Manifest main attributes"
. После того, как я удалил файлы подписи вручную, ошибка исчезла.
Я попытался отфильтровать файлы подписи в моем ant -file с excludes
-attribute или exclude
-tag, но ничего не имеет никакого эффекта.
Это 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>
Как фильтровать файлы из полученного jar в этой ant -task? Спасибо за вашу помощь!
Ответы
Ответ 1
Насколько я знаю, нет способа фильтровать при использовании <zipgroupfileset> : включенные/исключаемые используемые там применяются к зажимам, которые должны быть объединены, а не к содержанию внутри них.
Если у вас есть известный набор JAR для слияния, вы можете использовать индивидуальный <zipset> записи для каждого; этот подход позволяет использовать include/exclude для фильтрации содержимого исходного архива.
Альтернативный подход состоит в том, чтобы просто разархивировать все во временное место, удалить/изменить нежелательные биты, а затем закрепить все резервное копирование.
Ответ 2
carej прав. Я пытался это сделать, объединяя другие банки в моем приложении jar, исключая некоторые файлы, и нет возможности использовать для него <zipgroupfileset>
.
Мое решение - это вариант метода unzip/clean-up/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/в файл external-libs.jar, а затем я жду, пока вы не получите предупреждения о файлах с датами модификации в будущем, затем я объединю свои класса из каталога build/с содержимым external-libs.jar, исключая файлы в своем корне, которые в этом случае были файлами и примерами README.
Затем у меня есть свой собственный файл README, в котором перечислены все данные, необходимые для тех библиотек, которые я включаю в свое приложение, например, лицензию, веб-сайт и т.д.
Ответ 3
Вы можете использовать параметр exclude
в теге zipfileset
для удаления содержимого из объединенных внешних файлов JAR, так как это:
<jar jarfile="${dist}/lib/external-libs.jar">
<zipgroupfileset dir="lib/" excludes="META-INF/**/*">
<include name="**/*.jar"/>
</zipgroupfileset>
</jar>
В результате JAR файл будет неподписанным.
Ответ 4
Ответ 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>
Ответ 5
У меня также была такая же проблема. Много искал и нашел что-то, что сработало для меня.
Удалите файл jar файла.
META-INF/.SF,
META-INF/.DSA
файлы. Объедините его снова и запустите, не должно появляться сообщение об ошибке.
Объяснение причины объясняется здесь: http://qe-cafe.blogspot.in/2010/06/invalid-signature-file-digest-for.html
Ответ 6
В течение нескольких часов он боролся с одной и той же проблемой, поэтому закончил работу над новой задачей, расширив существующую:
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>