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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+