diff --git a/src/main/org/apache/tools/ant/helper/ProjectHelper2.java b/src/main/org/apache/tools/ant/helper/ProjectHelper2.java index 6daff3b14..5c3a1667a 100644 --- a/src/main/org/apache/tools/ant/helper/ProjectHelper2.java +++ b/src/main/org/apache/tools/ant/helper/ProjectHelper2.java @@ -32,6 +32,7 @@ import org.apache.tools.ant.types.resources.FileProvider; import org.apache.tools.ant.types.resources.URLProvider; import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.JAXPUtils; +import org.apache.tools.zip.ZipFile; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.Locator; @@ -231,6 +232,7 @@ public class ProjectHelper2 extends ProjectHelper { } InputStream inputStream = null; InputSource inputSource = null; + ZipFile zf = null; try { /** @@ -243,16 +245,26 @@ public class ProjectHelper2 extends ProjectHelper { uri = FILE_UTILS.toURI(buildFile.getAbsolutePath()); inputStream = new FileInputStream(buildFile); } else { - inputStream = url.openStream(); - uri = url.toString(); // ?? OK ?? + uri = url.toString(); + int pling = -1; + if (uri.startsWith("jar:file") + && (pling = uri.indexOf("!")) > -1) { + zf = new ZipFile(org.apache.tools.ant.launch.Locator + .fromJarURI(uri), "UTF-8"); + inputStream = + zf.getInputStream(zf.getEntry(uri.substring(pling + 1))); + } else { + inputStream = url.openStream(); + } } inputSource = new InputSource(inputStream); if (uri != null) { inputSource.setSystemId(uri); } - project.log("parsing buildfile " + buildFileName + " with URI = " + uri, - Project.MSG_VERBOSE); + project.log("parsing buildfile " + buildFileName + " with URI = " + + uri + (zf != null ? " from a zip file" : ""), + Project.MSG_VERBOSE); DefaultHandler hb = handler; @@ -290,6 +302,7 @@ public class ProjectHelper2 extends ProjectHelper { + exc.getMessage(), exc); } finally { FileUtils.close(inputStream); + ZipFile.closeQuietly(zf); } } diff --git a/src/main/org/apache/tools/ant/taskdefs/CloseResources.java b/src/main/org/apache/tools/ant/taskdefs/CloseResources.java new file mode 100644 index 000000000..29b0caedc --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/CloseResources.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.tools.ant.taskdefs; + +import java.io.IOException; +import java.net.URL; +import java.util.Iterator; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Resource; +import org.apache.tools.ant.types.ResourceCollection; +import org.apache.tools.ant.types.resources.URLProvider; +import org.apache.tools.ant.types.resources.Union; +import org.apache.tools.ant.util.FileUtils; + +/** + * Not a real task but used during tests. + * + * Closes the resources associated with an URL. In particular this is + * going to close the jars associated with a jar:file: URL - and it + * does so in a way that the Java VM still thinks it is open, so use + * it at your own risk. + */ +public class CloseResources extends Task { + private Union resources = new Union(); + + public void add(ResourceCollection rc) { + resources.add(rc); + } + + public void execute() { + for (Iterator it = resources.iterator(); it.hasNext(); ) { + Resource r = (Resource) it.next(); + URLProvider up = (URLProvider) r.as(URLProvider.class); + if (up != null) { + URL u = up.getURL(); + try { + FileUtils.close(u.openConnection()); + } catch (IOException ex) { + // ignore + } + } + } + } +} \ No newline at end of file diff --git a/src/main/org/apache/tools/ant/types/resources/URLResource.java b/src/main/org/apache/tools/ant/types/resources/URLResource.java index e391be6f1..067226870 100644 --- a/src/main/org/apache/tools/ant/types/resources/URLResource.java +++ b/src/main/org/apache/tools/ant/types/resources/URLResource.java @@ -22,12 +22,9 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.net.MalformedURLException; -import java.net.JarURLConnection; -import java.util.jar.JarFile; import org.apache.tools.ant.Project; import org.apache.tools.ant.BuildException; @@ -392,21 +389,10 @@ public class URLResource extends Resource implements URLProvider { * */ private synchronized void close() { - if (conn != null) { - try { - if (conn instanceof JarURLConnection) { - JarURLConnection juc = (JarURLConnection) conn; - JarFile jf = juc.getJarFile(); - jf.close(); - jf = null; - } else if (conn instanceof HttpURLConnection) { - ((HttpURLConnection) conn).disconnect(); - } - } catch (IOException exc) { - //ignore - } finally { - conn = null; - } + try { + FileUtils.close(conn); + } finally { + conn = null; } } diff --git a/src/main/org/apache/tools/ant/util/FileUtils.java b/src/main/org/apache/tools/ant/util/FileUtils.java index 381878640..9bcd5bc95 100644 --- a/src/main/org/apache/tools/ant/util/FileUtils.java +++ b/src/main/org/apache/tools/ant/util/FileUtils.java @@ -27,7 +27,10 @@ import java.io.Reader; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.net.MalformedURLException; +import java.net.HttpURLConnection; +import java.net.JarURLConnection; import java.net.URL; +import java.net.URLConnection; import java.nio.channels.Channel; import java.text.DecimalFormat; import java.util.ArrayList; @@ -38,6 +41,7 @@ import java.util.Random; import java.util.Stack; import java.util.StringTokenizer; import java.util.Vector; +import java.util.jar.JarFile; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.PathTokenizer; @@ -1444,6 +1448,30 @@ public class FileUtils { } } + /** + * Closes an URLConnection if its concrete implementation provides + * a way to close it that Ant knows of. + * + * @param conn connection, can be null + * @since Ant 1.8.0 + */ + public static void close(URLConnection conn) { + if (conn != null) { + try { + if (conn instanceof JarURLConnection) { + JarURLConnection juc = (JarURLConnection) conn; + JarFile jf = juc.getJarFile(); + jf.close(); + jf = null; + } else if (conn instanceof HttpURLConnection) { + ((HttpURLConnection) conn).disconnect(); + } + } catch (IOException exc) { + //ignore + } + } + } + /** * Delete the file with {@link File#delete()} if the argument is not null. * Do nothing on a null argument. diff --git a/src/tests/antunit/taskdefs/import-url-test.xml b/src/tests/antunit/taskdefs/import-url-test.xml index f194bff62..ab4f0d495 100644 --- a/src/tests/antunit/taskdefs/import-url-test.xml +++ b/src/tests/antunit/taskdefs/import-url-test.xml @@ -57,4 +57,16 @@ foo=bar + + + + + + + + + + + diff --git a/src/tests/antunit/types/javaresource-test.xml b/src/tests/antunit/types/javaresource-test.xml new file mode 100644 index 000000000..dddf3f48f --- /dev/null +++ b/src/tests/antunit/types/javaresource-test.xml @@ -0,0 +1,63 @@ + + + + + + + + Hello, world + a=b + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +