diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 115bbeef1..b28cbc824 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -20,6 +20,7 @@ Balazs Fejes 2 Benjamin Burgess Ben Galbraith Benoit Moussaud +Bernd Dutkowski Brad Clark Brant Langer Gurganus Brian Deitte diff --git a/WHATSNEW b/WHATSNEW index 50c9cfb55..734ac03c2 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -34,6 +34,8 @@ Other changes: * Add condition. Bugzilla report 28883. +* Extending JAR-Task for SPI. Bugzilla report 31520. + Changes from Ant 1.7.0Beta1 to Ant 1.7.0Beta2 ============================================= diff --git a/contributors.xml b/contributors.xml index 6b6efaf44..e0cac7ad6 100644 --- a/contributors.xml +++ b/contributors.xml @@ -88,6 +88,10 @@ Benoit Moussaud + + Bernd + Dutkowski + Brad Clark diff --git a/docs/manual/CoreTasks/jar.html b/docs/manual/CoreTasks/jar.html index f1f9c9b72..f7c674856 100644 --- a/docs/manual/CoreTasks/jar.html +++ b/docs/manual/CoreTasks/jar.html @@ -60,10 +60,10 @@ of two seconds. If a file is less than two seconds newer than the entry in the archive, Ant will not consider it newer.

The whenmanifestonly parameter controls what happens when no -files, apart from the manifest file, match. +files, apart from the manifest file, or nested services, match. If skip, the JAR is not created and a warning is issued. If fail, the JAR is not created and the build is halted with an error. -If create, (default) an empty JAR file (only containing a manifest) +If create, (default) an empty JAR file (only containing a manifest and services) is created.

(The Jar task is a shortcut for specifying the manifest file of a JAR file. @@ -82,7 +82,7 @@ being wrapped and continued on the next line. 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".

+to a value other than its default, "add".

Parameters

@@ -278,7 +278,52 @@ depend on your manifest:

This task will not create any index entries for archives that are empty or only contain files inside the META-INF directory.

+

service

+

since ant 1.7.0

+ +

+ The nested server element specifies a service. + Services are described by + http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider. + The approach is to have providers JARs include files named by the service + provided, for example, + META-INF/services/javax.script.ScriptEngineFactory + which can include implementation class names, one per line (usually just one per JAR). + + The name of the + service is set by the "type" attribute. The classname implementing + the service is the the "provider" attribute, or it one wants to + specify a number of classes that implement the service, by + "provider" nested elements. +

+

+

+ + + + + + + + + + + + + + + +
AttributeDescriptionRequired
typeThe name of the service.Yes
provider + The classname of the class implemening the service. + Yes, unless there is a nested + <provider> element.
+

+ The provider classname is specified either by the "provider" attribute, or + by a nested <provider> element, which has a single "classname" attribute. + If a JAR file has more that one implementation of the service, a number of + nested <provider> elements may be used. +

Examples

  <jar destfile="${dist}/lib/app.jar" basedir="${build}/classes"/>

jars all files in the ${build}/classes directory into a file @@ -336,6 +381,28 @@ Name: common/MyClass.class Sealed: false - +

+ The following shows how to create a jar file specifing a service + with an implementation of the JDK6 scripting interface: +

+
<jar jarfile="pinky.jar">
+  <fileset dir="build/classes"/>
+  <service type="javax.script.ScriptEngineFactory"
+           provider="org.acme.PinkyLanguage"/>
+</jar>
+
+

+ The following shows how to create a jar file specifing a service + with two implementations of the JDK6 scripting interface: +

+
+<jar jarfile="pinkyandbrain.jar">
+  <fileset dir="classes"/>
+  <service type="javax.script.ScriptEngineFactory">
+    <provider classname="org.acme.PinkyLanguage"/>
+    <provider classname="org.acme.BrainLanguage"/>
+  </service>
+</jar>
+
diff --git a/src/main/org/apache/tools/ant/taskdefs/Jar.java b/src/main/org/apache/tools/ant/taskdefs/Jar.java index ffa41bb63..1ff4af1b0 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Jar.java +++ b/src/main/org/apache/tools/ant/taskdefs/Jar.java @@ -48,6 +48,7 @@ import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.ResourceCollection; import org.apache.tools.ant.types.ZipFileSet; +import org.apache.tools.ant.types.spi.Service; import org.apache.tools.zip.JarMarker; import org.apache.tools.zip.ZipExtraField; import org.apache.tools.zip.ZipOutputStream; @@ -66,6 +67,11 @@ public class Jar extends Zip { /** The manifest file name. */ private static final String MANIFEST_NAME = "META-INF/MANIFEST.MF"; + /** + * List of all known SPI Services + */ + private List serviceList = new ArrayList(); + /** merged manifests added through addConfiguredManifest */ private Manifest configuredManifest; /** shadow of the above if upToDate check alters the value */ @@ -367,6 +373,36 @@ public class Jar extends Zip { indexJars.append(p); } + /** + * A nested SPI service element. + * @param service the nested element. + * @since Ant 1.7 + */ + public void addConfiguredService(Service service) { + // Check if the service is configured correctly + service.check(); + serviceList.add(service); + } + + /** + * Write SPI Information to JAR + */ + private void writeServices(ZipOutputStream zOut) throws IOException { + Iterator serviceIterator; + Service service; + + serviceIterator = serviceList.iterator(); + while(serviceIterator.hasNext()){ + service = (Service) serviceIterator.next(); + //stolen from writeManifest + super.zipFile(service.getAsStream(), zOut, + "META-INF/service/" + service.getType(), + System.currentTimeMillis(), null, + ZipFileSet.DEFAULT_FILE_MODE); + } + } + + /** * Initialize the zip output stream. * @param zOut the zip output stream @@ -379,6 +415,7 @@ public class Jar extends Zip { if (!skipWriting) { Manifest jarManifest = createManifest(); writeManifest(zOut, jarManifest); + writeServices(zOut); } }