Browse Source

try a bit harder to close the archive when reading a build file. Since that still doesn't work, add a task to brutally close jars and use it in import-url-test

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@890827 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 15 years ago
parent
commit
6cb11c4a23
6 changed files with 184 additions and 22 deletions
  1. +17
    -4
      src/main/org/apache/tools/ant/helper/ProjectHelper2.java
  2. +60
    -0
      src/main/org/apache/tools/ant/taskdefs/CloseResources.java
  3. +4
    -18
      src/main/org/apache/tools/ant/types/resources/URLResource.java
  4. +28
    -0
      src/main/org/apache/tools/ant/util/FileUtils.java
  5. +12
    -0
      src/tests/antunit/taskdefs/import-url-test.xml
  6. +63
    -0
      src/tests/antunit/types/javaresource-test.xml

+ 17
- 4
src/main/org/apache/tools/ant/helper/ProjectHelper2.java View File

@@ -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);
}
}



+ 60
- 0
src/main/org/apache/tools/ant/taskdefs/CloseResources.java View File

@@ -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
}
}
}
}
}

+ 4
- 18
src/main/org/apache/tools/ant/types/resources/URLResource.java View File

@@ -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;
}
}



+ 28
- 0
src/main/org/apache/tools/ant/util/FileUtils.java View File

@@ -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.


+ 12
- 0
src/tests/antunit/taskdefs/import-url-test.xml View File

@@ -57,4 +57,16 @@ foo=bar
<au:assertLogContains text="type is url"/>
<au:assertLogContains text="foo is bar"/>
</target>

<target name="tearDown" depends="close, antunit-base.tearDown"/>

<target name="close">
<taskdef name="close"
classname="org.apache.tools.ant.taskdefs.CloseResources"/>
<close>
<javaresource name="a/b/outer.xml">
<classpath location="${output}/test.jar"/>
</javaresource>
</close>
</target>
</project>

+ 63
- 0
src/tests/antunit/types/javaresource-test.xml View File

@@ -0,0 +1,63 @@
<?xml version="1.0"?>
<!--
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.
-->
<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
<import file="../antunit-base.xml" />

<target name="setUp">
<mkdir dir="${input}"/>
<echo file="${input}/foo.txt">Hello, world</echo>
<echo file="${input}/x.properties">a=b</echo>
<mkdir dir="${output}"/>
<jar destfile="${output}/javaresource-test.jar">
<fileset dir="${input}"/>
</jar>
</target>

<target name="testReadFromFile" depends="setUp">
<concat>
<javaresource name="foo.txt">
<classpath location="${input}"/>
</javaresource>
</concat>
<au:assertLogContains text="Hello, world"/>
<loadproperties>
<javaresource name="x.properties">
<classpath location="${input}"/>
</javaresource>
</loadproperties>
<au:assertPropertyEquals name="a" value="b"/>
</target>

<target name="testReadFromJar" depends="setUp">
<delete dir="${input}"/>
<concat>
<javaresource name="foo.txt">
<classpath location="${output}/javaresource-test.jar"/>
</javaresource>
</concat>
<au:assertLogContains text="Hello, world"/>
<loadproperties>
<javaresource name="x.properties">
<classpath location="${output}/javaresource-test.jar"/>
</javaresource>
</loadproperties>
<au:assertPropertyEquals name="a" value="b"/>
</target>
</project>


Loading…
Cancel
Save