diff --git a/src/main/org/apache/tools/ant/taskdefs/Jar.java b/src/main/org/apache/tools/ant/taskdefs/Jar.java index 92f072918..c8a3904d3 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Jar.java +++ b/src/main/org/apache/tools/ant/taskdefs/Jar.java @@ -531,11 +531,12 @@ public class Jar extends Zip { * out-of-date. Subclasses overriding this method are supposed to * set this value correctly in their call to * super.getResourcesToAdd. - * @return an array of resources to add for each fileset passed in. + * @return an array of resources to add for each fileset passed in as well + * as a flag that indicates whether the archive is uptodate. * * @exception BuildException if it likes */ - protected Resource[][] getResourcesToAdd(FileSet[] filesets, + protected ArchiveState getResourcesToAdd(FileSet[] filesets, File zipFile, boolean needsUpdate) throws BuildException { @@ -581,7 +582,8 @@ public class Jar extends Zip { ZipOutputStream zOut = null; try { - log("Building jar: " + getDestFile().getAbsolutePath()); + log("Building MANIFEST-only jar: " + + getDestFile().getAbsolutePath()); zOut = new ZipOutputStream(new FileOutputStream(getDestFile())); zOut.setEncoding(getEncoding()); diff --git a/src/main/org/apache/tools/ant/taskdefs/Zip.java b/src/main/org/apache/tools/ant/taskdefs/Zip.java index 12e531a95..9c54ab8a3 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Zip.java +++ b/src/main/org/apache/tools/ant/taskdefs/Zip.java @@ -344,7 +344,11 @@ public class Zip extends MatchingTask { // we don't need to update if the original file doesn't exist addingNewFiles = true; - doUpdate = doUpdate && zipFile.exists(); + if (doUpdate && !zipFile.exists()) { + doUpdate = false; + log("ignoring update attribute as " + archiveType + + " doesn't exist.", Project.MSG_DEBUG); + } // Add the files found in groupfileset to fileset for (int i = 0; i < groupfilesets.size(); i++) { @@ -381,14 +385,16 @@ public class Zip extends MatchingTask { vfss.copyInto(fss); boolean success = false; try { - Resource[][] addThem = getResourcesToAdd(fss, zipFile, false); + // can also handle empty archives + ArchiveState state = getResourcesToAdd(fss, zipFile, false); // quick exit if the target is up to date - // can also handle empty archives - if (isEmpty(addThem)) { + if (!state.isOutOfDate()) { return; } + Resource[][] addThem = state.getResourcesToAdd(); + if (doUpdate) { renamedFile = fileUtils.createTempFile("zip", ".tmp", @@ -687,17 +693,38 @@ public class Zip extends MatchingTask { * out-of-date. Subclasses overriding this method are supposed to * set this value correctly in their call to * super.getResourcesToAdd. - * @return an array of resources to add for each fileset passed in. + * @return an array of resources to add for each fileset passed in as well + * as a flag that indicates whether the archive is uptodate. * * @exception BuildException if it likes */ - protected Resource[][] getResourcesToAdd(FileSet[] filesets, + protected ArchiveState getResourcesToAdd(FileSet[] filesets, File zipFile, boolean needsUpdate) throws BuildException { Resource[][] initialResources = grabResources(filesets); if (isEmpty(initialResources)) { + if (needsUpdate && doUpdate) { + /* + * This is a rather hairy case. + * + * One of our subclasses knows that we need to update the + * archive, but at the same time, there are no resources + * known to us that would need to be added. Only the + * subclass seems to know what's going on. + * + * This happens if detects that the manifest has changed, + * for example. The manifest is not part of any resources + * because of our support for inline s. + * + * If we invoke createEmptyZip like Ant 1.5.2 did, + * we'll loose all stuff that has been in the original + * archive (bugzilla report 17780). + */ + return new ArchiveState(true, initialResources); + } + if (emptyBehavior.equals("skip")) { if (doUpdate) { log(archiveType + " archive " + zipFile @@ -717,16 +744,18 @@ public class Zip extends MatchingTask { // Create. createEmptyZip(zipFile); } - return initialResources; + return new ArchiveState(needsUpdate, initialResources); } + // initialResources is not empty + if (!zipFile.exists()) { - return initialResources; + return new ArchiveState(true, initialResources); } if (needsUpdate && !doUpdate) { // we are recreating the archive, need all resources - return initialResources; + return new ArchiveState(true, initialResources); } Resource[][] newerResources = new Resource[filesets.length][]; @@ -794,10 +823,10 @@ public class Zip extends MatchingTask { if (needsUpdate && !doUpdate) { // we are recreating the archive, need all resources - return initialResources; + return new ArchiveState(true, initialResources); } - return newerResources; + return new ArchiveState(needsUpdate, newerResources); } /** @@ -1096,4 +1125,28 @@ public class Zip extends MatchingTask { return new String[] {"add", "preserve", "fail"}; } } + + /** + * Holds the up-to-date status and the out-of-date resources of + * the original archive. + * + * @since Ant 1.5.3 + */ + public static class ArchiveState { + private boolean outOfDate; + private Resource[][] resourcesToAdd; + + ArchiveState(boolean state, Resource[][] r) { + outOfDate = state; + resourcesToAdd = r; + } + + public boolean isOutOfDate() { + return outOfDate; + } + + public Resource[][] getResourcesToAdd() { + return resourcesToAdd; + } + } }