diff --git a/build.xml b/build.xml
index e17f4e51f..0c7668930 100644
--- a/build.xml
+++ b/build.xml
@@ -1547,6 +1547,22 @@
+
+
+
+
+
+
+
+
+
diff --git a/docs/manual/CoreTasks/jar.html b/docs/manual/CoreTasks/jar.html
index 4c278415b..c4f88c1df 100644
--- a/docs/manual/CoreTasks/jar.html
+++ b/docs/manual/CoreTasks/jar.html
@@ -73,14 +73,17 @@ attribute of a zipfileset in a Zip task. The one difference is that if the
include an empty one for you.)
Manifests are processed by the Jar task according to the
-Jar file specification.
+Jar file specification.
Note in particular that this may result in manifest lines greater than 72 bytes
-being wrapped and continued on the next line.
-
+being wrapped and continued on the next line.
+
+The Jar task checks whether you specified package information according to the
+
+versioning specification.
Please note that the zip format allows multiple files of the same
-fully-qualified name to exist within a single archive. This has been
-documented as causing various problems for unsuspecting users. If you wish
+fully-qualified name to exist within a single archive. This has been
+documented as causing various problems for unsuspecting users. If you wish
to avoid this behavior you must set the duplicate
attribute
to a value other than its default, "add"
.
diff --git a/src/etc/testcases/taskdefs/jar.xml b/src/etc/testcases/taskdefs/jar.xml
index 5001f29a3..1f12bcc56 100644
--- a/src/etc/testcases/taskdefs/jar.xml
+++ b/src/etc/testcases/taskdefs/jar.xml
@@ -236,5 +236,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/org/apache/tools/ant/taskdefs/Jar.java b/src/main/org/apache/tools/ant/taskdefs/Jar.java
index f10098674..e3c6e3d29 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Jar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Jar.java
@@ -45,6 +45,7 @@ import java.util.zip.ZipFile;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Manifest.Section;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.ResourceCollection;
@@ -76,6 +77,7 @@ public class Jar extends Zip {
/** merged manifests added through addConfiguredManifest */
private Manifest configuredManifest;
+
/** shadow of the above if upToDate check alters the value */
private Manifest savedConfiguredManifest;
@@ -158,7 +160,7 @@ public class Jar extends Zip {
setEncoding("UTF8");
rootEntries = new Vector();
}
-
+
/**
* Not used for jar files.
* @param we not used
@@ -773,6 +775,25 @@ public class Jar extends Zip {
*/
protected void cleanUp() {
super.cleanUp();
+
+ // check against packaging spec
+ // http://java.sun.com/j2se/1.3/docs/guide/versioning/spec/VersioningSpecification.html#PackageVersioning
+ Section mainSection = (configuredManifest==null) ? null : configuredManifest.getMainSection();
+ if (mainSection==null) {
+ log("No Implementation-Title set. (" + getLocation() + ")");
+ log("No Implementation-Version set. (" + getLocation() + ")");
+ log("No Implementation-Vendor set. (" + getLocation() + ")");
+ } else {
+ if (mainSection.getAttribute("Implementation-Title") == null) {
+ log("No Implementation-Title set. (" + getLocation() + ")");
+ }
+ if (mainSection.getAttribute("Implementation-Version") == null) {
+ log("No Implementation-Version set. (" + getLocation() + ")");
+ }
+ if (mainSection.getAttribute("Implementation-Vendor") == null) {
+ log("No Implementation-Vendor set. (" + getLocation() + ")");
+ }
+ }
// we want to save this info if we are going to make another pass
if (!doubleFilePass || !skipWriting) {
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/JarTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/JarTest.java
index 726956ee8..f5ad7092c 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/JarTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/JarTest.java
@@ -267,4 +267,19 @@ public class JarTest extends BuildFileTest {
public void testIndexJarsPlusJarMarker() {
executeTarget("testIndexJarsPlusJarMarker");
}
+
+ public void testNoVersionInfo() {
+ executeTarget("testNoVersionInfo");
+ assertLogContaining("No Implementation-Title set.");
+ assertLogContaining("No Implementation-Version set.");
+ assertLogContaining("No Implementation-Vendor set.");
+ }
+
+ public void testHasVersionInfo() {
+ executeTarget("testHasVersionInfo");
+ assertFalse( getLog().contains("No Implementation-Title set.") );
+ assertFalse( getLog().contains("No Implementation-Version set.") );
+ assertFalse( getLog().contains("No Implementation-Vendor set.") );
+ }
+
}