diff --git a/WHATSNEW b/WHATSNEW index 54be3f1bd..eba43380f 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -94,6 +94,8 @@ Fixed bugs: * build.sysclasspath will now be honored by more tasks. +* would remove the original manifest. + Other changes: -------------- * The filesetmanifest attribute of has been reenabled. diff --git a/src/main/org/apache/tools/ant/taskdefs/Jar.java b/src/main/org/apache/tools/ant/taskdefs/Jar.java index 4d19a21c3..869fafaaa 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Jar.java +++ b/src/main/org/apache/tools/ant/taskdefs/Jar.java @@ -1,7 +1,7 @@ /* * The Apache Software License, Version 1.1 * - * Copyright (c) 2000-2002 The Apache Software Foundation. All rights + * Copyright (c) 2000-2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -65,6 +65,8 @@ import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.Reader; import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.FileScanner; import org.apache.tools.ant.Project; @@ -96,6 +98,12 @@ public class Jar extends Zip { /** merged manifests added through filesets */ private Manifest filesetManifest; + /** + * Manifest of original archive, will be set to null if not in + * update mode. + */ + private Manifest originalManifest; + /** * whether to merge fileset manifests; * value is true if filesetmanifest is 'merge' or 'mergewithoutmain' @@ -145,6 +153,36 @@ public class Jar extends Zip { setDestFile(jarFile); } + /** + * Override to get hold of the original Manifest (if present and + * only if updating ... + * + * @since Ant 1.5.2 + */ + public void setDestFile(File jarFile) { + super.setDestFile(jarFile); + if (jarFile.exists()) { + try { + ZipFile zf = new ZipFile(jarFile); + + // must not use getEntry as "well behaving" applications + // must accept the manifest in any capitalization + Enumeration enum = zf.entries(); + while (enum.hasMoreElements()) { + ZipEntry ze = (ZipEntry) enum.nextElement(); + if (ze.getName().equalsIgnoreCase("META-INF/MANIFEST.MF")) { + originalManifest = + getManifest(new InputStreamReader(zf + .getInputStream(ze))); + } + } + } catch (Throwable t) { + log("error while reading original manifest: " + t.getMessage(), + Project.MSG_WARN); + } + } + } + /** * Set whether or not to create an index list for classes. * This may speed up classloading in some cases. @@ -272,6 +310,10 @@ public class Jar extends Zip { private Manifest createManifest() throws BuildException { try { + if (!isInUpdateMode()) { + originalManifest = null; + } + Manifest finalManifest = Manifest.getDefaultManifest(); if (manifest == null) { @@ -279,25 +321,22 @@ public class Jar extends Zip { // if we haven't got the manifest yet, attempt to // get it now and have manifest be the final merge manifest = getManifest(manifestFile); - finalManifest.merge(filesetManifest); - finalManifest.merge(configuredManifest); - finalManifest.merge(manifest, !mergeManifestsMain); - } else if (configuredManifest != null) { - // configuredManifest is the final merge - finalManifest.merge(filesetManifest); - finalManifest.merge(configuredManifest, - !mergeManifestsMain); - } else if (filesetManifest != null) { - // filesetManifest is the final (and only) merge - finalManifest.merge(filesetManifest, !mergeManifestsMain); } - } else { - // manifest is the final merge - finalManifest.merge(filesetManifest); - finalManifest.merge(configuredManifest); - finalManifest.merge(manifest, !mergeManifestsMain); } + /* + * Precedence: manifestFile wins over inline manifest, + * over manifests read from the filesets over the original + * manifest. + * + * merge with null argument is a no-op + */ + + finalManifest.merge(originalManifest); + finalManifest.merge(filesetManifest); + finalManifest.merge(configuredManifest); + finalManifest.merge(manifest, !mergeManifestsMain); + return finalManifest; } catch (ManifestException e) { @@ -307,7 +346,7 @@ public class Jar extends Zip { } private void writeManifest(ZipOutputStream zOut, Manifest manifest) - throws IOException { + throws IOException { for (Enumeration e = manifest.getWarnings(); e.hasMoreElements();) { log("Manifest warning: " + (String) e.nextElement(), @@ -330,7 +369,7 @@ public class Jar extends Zip { } protected void finalizeZipOutputStream(ZipOutputStream zOut) - throws IOException, BuildException { + throws IOException, BuildException { if (index) { createIndexList(zOut); @@ -399,9 +438,9 @@ public class Jar extends Zip { int mode) throws IOException { if ("META-INF/MANIFEST.MF".equalsIgnoreCase(vPath)) { - if (! doubleFilePass || (doubleFilePass && skipWriting)) { - filesetManifest(file, null); - } + if (! doubleFilePass || (doubleFilePass && skipWriting)) { + filesetManifest(file, null); + } } else { super.zipFile(file, zOut, vPath, mode); } @@ -414,9 +453,9 @@ public class Jar extends Zip { long lastModified, File file, int mode) throws IOException { if ("META-INF/MANIFEST.MF".equalsIgnoreCase(vPath)) { - if (! doubleFilePass || (doubleFilePass && skipWriting)) { - filesetManifest(file, is); - } + if (! doubleFilePass || (doubleFilePass && skipWriting)) { + filesetManifest(file, is); + } } else { super.zipFile(is, zOut, vPath, lastModified, null, mode); } @@ -542,11 +581,11 @@ public class Jar extends Zip { // we want to save this info if we are going to make another pass if (! doubleFilePass || (doubleFilePass && ! skipWriting)) - { - manifest = null; - configuredManifest = savedConfiguredManifest; - filesetManifest = null; - } + { + manifest = null; + configuredManifest = savedConfiguredManifest; + filesetManifest = null; + } } /** diff --git a/src/testcases/org/apache/tools/ant/taskdefs/JarTest.java b/src/testcases/org/apache/tools/ant/taskdefs/JarTest.java index 1ece1010e..e4c6ff106 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/JarTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/JarTest.java @@ -152,7 +152,7 @@ public class JarTest extends BuildFileTest { jarModifiedDate < jarFile.lastModified()); } - public void XtestManifestStaysIntact() + public void testManifestStaysIntact() throws IOException, ManifestException { executeTarget("testManifestStaysIntact"); Manifest mf1 =