added workaround for Ant bug in 1.8.0 and 1.8.1 versions regarding custom manifest (IDEA-66287)

This commit is contained in:
nik
2011-04-07 15:03:36 +04:00
parent be1465fc8e
commit b89242abe6
5 changed files with 178 additions and 46 deletions
@@ -1,46 +1,50 @@
package jetbrains.antlayout.datatypes;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.taskdefs.Jar;
import org.apache.tools.ant.taskdefs.Manifest;
import org.apache.tools.ant.taskdefs.ManifestException;
import org.apache.tools.ant.types.ZipFileSet;
import org.apache.tools.ant.types.Path;
import java.io.File;
/**
* @author max
*/
public class JarContainer extends ZipContainer {
protected Zip createTask() {
Jar task = new Jar();
task.setTaskName("jar");
task.setWhenmanifestonly((Zip.WhenEmpty) Zip.WhenEmpty.getInstance(Zip.WhenEmpty.class, "skip"));
return task;
}
public void setIndex(boolean flag) {
((Jar) task).setIndex(flag);
}
public void setManifestEncoding(String manifestEncoding) {
((Jar) task).setManifestEncoding(manifestEncoding);
}
public void setManifest(File manifestFile) {
((Jar) task).setManifest(manifestFile);
}
public void setFilesetmanifest(Jar.FilesetManifestConfig config) {
((Jar) task).setFilesetmanifest(config);
}
public void addConfiguredManifest(Manifest newManifest) throws ManifestException {
((Jar) task).addConfiguredManifest(newManifest);
}
public void addMetainf(ZipFileSet fs) {
((Jar) task).addMetainf(fs);
}
}
package jetbrains.antlayout.datatypes;
import org.apache.tools.ant.Main;
import org.apache.tools.ant.taskdefs.*;
import org.apache.tools.ant.types.ZipFileSet;
import java.io.File;
/**
* @author max
*/
public class JarContainer extends ZipContainer {
protected Zip createTask() {
String version = Main.getAntVersion();
Jar task;
if (version != null && (version.indexOf("1.8.0") != -1 || version.indexOf("1.8.1") != -1)) {
task = new PatchedJar();
}
else {
task = new Jar();
}
task.setTaskName("jar");
task.setWhenmanifestonly((Zip.WhenEmpty) Zip.WhenEmpty.getInstance(Zip.WhenEmpty.class, "skip"));
return task;
}
public void setIndex(boolean flag) {
((Jar) task).setIndex(flag);
}
public void setManifestEncoding(String manifestEncoding) {
((Jar) task).setManifestEncoding(manifestEncoding);
}
public void setManifest(File manifestFile) {
((Jar) task).setManifest(manifestFile);
}
public void setFilesetmanifest(Jar.FilesetManifestConfig config) {
((Jar) task).setFilesetmanifest(config);
}
public void addConfiguredManifest(Manifest newManifest) throws ManifestException {
((Jar) task).addConfiguredManifest(newManifest);
}
public void addMetainf(ZipFileSet fs) {
((Jar) task).addMetainf(fs);
}
}
@@ -0,0 +1,83 @@
package org.apache.tools.ant.taskdefs;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Jar;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.types.ArchiveFileSet;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import java.io.File;
/**
* This class is added to workaround https://issues.apache.org/bugzilla/show_bug.cgi?id=49605
* in Ant 1.8.0 and 1.8.1
*
* @author nik
*/
public class PatchedJar extends Jar {
private static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";
@Override
protected ArchiveState getResourcesToAdd(ResourceCollection[] rcs, File zipFile, boolean needsUpdate) throws BuildException {
if (skipWriting) {
// this pass is only there to construct the merged
// manifest this means we claim an update was needed and
// only include the manifests, skipping any uptodate
// checks here defering them for the second run
Resource[][] manifests = grabManifests(rcs);
int count = 0;
for (int i = 0; i < manifests.length; i++) {
count += manifests[i].length;
}
log("found a total of " + count + " manifests in "
+ manifests.length + " resource collections",
Project.MSG_VERBOSE);
return new ArchiveState(true, manifests);
}
return super.getResourcesToAdd(rcs, zipFile, needsUpdate);
}
/**
* This method is copied from Jar class in Ant 1.8.2
*/
private Resource[][] grabManifests(ResourceCollection[] rcs) {
Resource[][] manifests = new Resource[rcs.length][];
for (int i = 0; i < rcs.length; i++) {
Resource[][] resources = null;
if (rcs[i] instanceof FileSet) {
resources = grabResources(new FileSet[] {(FileSet) rcs[i]});
} else {
resources = grabNonFileSetResources(new ResourceCollection[] {
rcs[i]
});
}
for (int j = 0; j < resources[0].length; j++) {
String name = resources[0][j].getName().replace('\\', '/');
if (rcs[i] instanceof ArchiveFileSet) {
ArchiveFileSet afs = (ArchiveFileSet) rcs[i];
if (!"".equals(afs.getFullpath(getProject()))) {
name = afs.getFullpath(getProject());
} else if (!"".equals(afs.getPrefix(getProject()))) {
String prefix = afs.getPrefix(getProject());
if (!prefix.endsWith("/") && !prefix.endsWith("\\")) {
prefix += "/";
}
name = prefix + name;
}
}
if (name.equalsIgnoreCase(MANIFEST_NAME)) {
manifests[i] = new Resource[] {resources[0][j]};
break;
}
}
if (manifests[i] == null) {
manifests[i] = new Resource[0];
}
}
return manifests;
}
}
@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: MyClass
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ArtifactManager">
<artifact type="jar" name="simple">
<output-path>$PROJECT_DIR$/out/artifacts/simple</output-path>
<root id="archive" name="simple.jar">
<element id="directory" name="META-INF">
<element id="file-copy" path="$PROJECT_DIR$/META-INF/MANIFEST.MF" />
</element>
</root>
</artifact>
</component>
<component name="ProjectModuleManager">
<modules>
</modules>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
@@ -0,0 +1,21 @@
package org.jetbrains.jps
import java.util.jar.Manifest
import org.jetbrains.jps.util.ZipUtil
import java.util.jar.Attributes
/**
* @author nik
*/
class ManifestInArtifactTest extends JpsBuildTestCase {
public void test() {
def project = buildAll("testData/manifestInArtifact/manifest.ipr", [:], {})
File jarFile = new File(project.targetFolder + "/artifacts/simple/simple.jar")
assertTrue(jarFile.exists())
File extracted = ZipUtil.extractToTempDir(jarFile)
File manifestFile = new File(extracted, "META-INF/MANIFEST.MF")
assertTrue(manifestFile.exists())
Manifest manifest = new Manifest(new FileInputStream(manifestFile))
assertEquals("MyClass", manifest.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS))
}
}