Browse Source

Bug 42275 running ant off a network share can cause Ant to fail

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@631263 13f79535-47bb-0310-9956-ffa450edef68
master
Steve Loughran 17 years ago
parent
commit
6e72d89be8
3 changed files with 132 additions and 21 deletions
  1. +66
    -9
      src/main/org/apache/tools/ant/launch/Launcher.java
  2. +28
    -8
      src/main/org/apache/tools/ant/launch/Locator.java
  3. +38
    -4
      src/tests/junit/org/apache/tools/ant/launch/LocatorTest.java

+ 66
- 9
src/main/org/apache/tools/ant/launch/Launcher.java View File

@@ -59,6 +59,11 @@ public class Launcher {
*/
public static final String ANT_PRIVATELIB = "lib";

/**
* launch diagnostics flag; for debugging trouble at launch time.
*/
public static boolean launchDiag = false;

/**
* The location of a per-user library directory.
* <p>
@@ -110,6 +115,9 @@ public class Launcher {
t.printStackTrace(System.err);
}
if (exitCode != 0) {
if (launchDiag) {
System.out.println("Exit code: "+exitCode);
}
System.exit(exitCode);
}
}
@@ -122,6 +130,7 @@ public class Launcher {
* @param getJars if true and a path is a directory, add the jars in
* the directory to the path urls
* @param libPathURLs the list of paths to add to
* @throws MalformedURLException if we can't create a URL
*/
private void addPath(String path, boolean getJars, List libPathURLs)
throws MalformedURLException {
@@ -129,18 +138,21 @@ public class Launcher {
while (tokenizer.hasMoreElements()) {
String elementName = tokenizer.nextToken();
File element = new File(elementName);
if (elementName.indexOf("%") != -1 && !element.exists()) {
if (elementName.indexOf('%') != -1 && !element.exists()) {
continue;
}
if (getJars && element.isDirectory()) {
// add any jars in the directory
URL[] dirURLs = Locator.getLocationURLs(element);
for (int j = 0; j < dirURLs.length; ++j) {
if (launchDiag) { System.out.println("adding library JAR: " + dirURLs[j]);}
libPathURLs.add(dirURLs[j]);
}
}

libPathURLs.add(Locator.fileToURL(element));
URL url = Locator.fileToURL(element);
if (launchDiag) { System.out.println("adding library URL: " + url) ;}
libPathURLs.add(url);
}
}

@@ -150,8 +162,9 @@ public class Launcher {
* @param args the command line arguments
* @return an exit code. As the normal ant main calls exit when it ends,
* this is for handling failures at bind-time
* @exception MalformedURLException if the URLs required for the classloader
* @throws MalformedURLException if the URLs required for the classloader
* cannot be created.
* @throws LaunchException for launching problems
*/
private int run(String[] args)
throws LaunchException, MalformedURLException {
@@ -168,12 +181,12 @@ public class Launcher {

if (antHome == null || !antHome.exists()) {
antHome = jarDir.getParentFile();
System.setProperty(ANTHOME_PROPERTY, antHome.getAbsolutePath());
setProperty(ANTHOME_PROPERTY, antHome.getAbsolutePath());
}

if (!antHome.exists()) {
throw new LaunchException("Ant home is set incorrectly or "
+ "ant could not be located");
+ "ant could not be located (estimated value="+antHome.getAbsolutePath()+")");
}

List libPaths = new ArrayList();
@@ -202,6 +215,8 @@ public class Launcher {
cpString = args[++i];
} else if (args[i].equals("--nouserlib") || args[i].equals("-nouserlib")) {
noUserLib = true;
} else if (args[i].equals("--launchdiag")) {
launchDiag = true;
} else if (args[i].equals("--noclasspath") || args[i].equals("-noclasspath")) {
noClassPath = true;
} else if (args[i].equals("-main")) {
@@ -215,6 +230,10 @@ public class Launcher {
}
}

logPath("Launcher JAR",sourceJar);
logPath("Launcher JAR directory", sourceJar.getParentFile());
logPath("java.home", new File(System.getProperty("java.home")));

//decide whether to copy the existing arg set, or
//build a new one from the list of all args excluding the special
//operations that only we handle
@@ -229,8 +248,10 @@ public class Launcher {
URL[] systemURLs = getSystemURLs(jarDir);
URL[] userURLs = noUserLib ? new URL[0] : getUserURLs();

File toolsJAR = Locator.getToolsJar();
logPath("tools.jar",toolsJAR);
URL[] jars = getJarArray(
libURLs, userURLs, systemURLs, Locator.getToolsJar());
libURLs, userURLs, systemURLs, toolsJAR);

// now update the class.path property
StringBuffer baseClassPath
@@ -245,12 +266,13 @@ public class Launcher {
baseClassPath.append(Locator.fromURI(jars[i].toString()));
}

System.setProperty(JAVA_CLASS_PATH, baseClassPath.toString());
setProperty(JAVA_CLASS_PATH, baseClassPath.toString());

URLClassLoader loader = new URLClassLoader(jars);
Thread.currentThread().setContextClassLoader(loader);
Class mainClass = null;
int exitCode = 0;
Throwable thrown=null;
try {
mainClass = loader.loadClass(mainClassname);
AntMain main = (AntMain) mainClass.newInstance();
@@ -261,9 +283,20 @@ public class Launcher {
File mainJar = Locator.getClassSource(mainClass);
System.err.println(
"Location of this class " + mainJar);
exitCode = EXIT_CODE_ERROR;
thrown = ex;
} catch (ClassNotFoundException cnfe) {
System.err.println(
"Failed to locate" + mainClassname);
thrown = cnfe;
} catch (Throwable t) {
t.printStackTrace(System.err);
thrown=t;
}
if(thrown!=null) {
System.err.println(ANTHOME_PROPERTY+": "+antHome.getAbsolutePath());
System.err.println("Classpath: " + baseClassPath.toString());
System.err.println("Launcher JAR: " + sourceJar.getAbsolutePath());
System.err.println("Launcher Directory: " + jarDir.getAbsolutePath());
exitCode = EXIT_CODE_ERROR;
}
return exitCode;
@@ -275,6 +308,7 @@ public class Launcher {
* @param cpString the classpath string
* @param libPaths the list of -lib entries.
* @return an array of URLs.
* @throws MalformedURLException if the URLs cannot be created.
*/
private URL[] getLibPathURLs(String cpString, List libPaths)
throws MalformedURLException {
@@ -296,6 +330,9 @@ public class Launcher {
* Get the jar files in ANT_HOME/lib.
* determine ant library directory for system jars: use property
* or default using location of ant-launcher.jar
* @param antLauncherDir the dir that ant-launcher ran from
* @return the URLs
* @throws MalformedURLException if the URLs cannot be created.
*/
private URL[] getSystemURLs(File antLauncherDir) throws MalformedURLException {
File antLibDir = null;
@@ -305,13 +342,15 @@ public class Launcher {
}
if ((antLibDir == null) || !antLibDir.exists()) {
antLibDir = antLauncherDir;
System.setProperty(ANTLIBDIR_PROPERTY, antLibDir.getAbsolutePath());
setProperty(ANTLIBDIR_PROPERTY, antLibDir.getAbsolutePath());
}
return Locator.getLocationURLs(antLibDir);
}

/**
* Get the jar files in user.home/.ant/lib
* @return the URLS from the user's lib dir
* @throws MalformedURLException if the URLs cannot be created.
*/
private URL[] getUserURLs() throws MalformedURLException {
File userLibDir
@@ -347,4 +386,22 @@ public class Launcher {
}
return jars;
}

/**
* set a system property, optionally log what is going on
* @param name property name
* @param value value
*/
private void setProperty(String name, String value) {
if (launchDiag) {
System.out.println("Setting \"" + name + "\" to \"" + value + "\"");
}
System.setProperty(name, value);
}

private void logPath(String name,File path) {
if(launchDiag) {
System.out.println(name+"= \""+path+"\"");
}
}
}

+ 28
- 8
src/main/org/apache/tools/ant/launch/Locator.java View File

@@ -144,9 +144,7 @@ public final class Locator {
String u = url.toString();
try {
if (u.startsWith("jar:file:")) {
int pling = u.indexOf("!");
String jarName = u.substring("jar:".length(), pling);
return new File(fromURI(jarName));
return new File(fromJarURI(u));
} else if (u.startsWith("file:")) {
int tail = u.indexOf(resource);
String dirName = u.substring(0, tail);
@@ -160,6 +158,8 @@ public final class Locator {
return null;
}



/**
* Constructs a file path from a <code>file:</code> URI.
*
@@ -238,13 +238,16 @@ public final class Locator {
return null;
}




/**
* package-private for testing in same classloader
* This method is public for testing; we may delete it without any warning -it is not part of Ant's stable API.
* @param uri uri to expand
* @return the decoded URI
* @since Ant1.7.1
*/
static String fromURIJava13(String uri) {
public static String fromURIJava13(String uri) {
// Fallback method for Java 1.3 or earlier.

URL url = null;
@@ -273,10 +276,14 @@ public final class Locator {
String path = null;
try {
path = decodeUri(uri);
//consider adding the current directory. This is not done when
//the path is a UNC name
String cwd = System.getProperty("user.dir");
int posi = cwd.indexOf(":");
if ((posi > 0) && path.startsWith(File.separator)) {
path = cwd.substring(0, posi + 1) + path;
int posi = cwd.indexOf(':');
boolean pathStartsWithFileSeparator = path.startsWith(File.separator);
boolean pathStartsWithUNC = path.startsWith("" + File.separator + File.separator);
if ((posi > 0) && pathStartsWithFileSeparator && !pathStartsWithUNC) {
path = cwd.substring(0, posi + 1) + path;
}
} catch (UnsupportedEncodingException exc) {
// not sure whether this is clean, but this method is
@@ -288,6 +295,19 @@ public final class Locator {
return path;
}

/**
* Crack a JAR URI.
* This method is public for testing; we may delete it without any warning -it is not part of Ant's stable API.
* @param uri uri to expand; contains jar: somewhere in it
* @return the decoded URI
* @since Ant1.7.1
*/
public static String fromJarURI(String uri) {
int pling = uri.indexOf('!');
String jarName = uri.substring("jar:".length(), pling);
return fromURI(jarName);
}

/**
* Decodes an Uri with % characters.
* The URI is escaped


+ 38
- 4
src/tests/junit/org/apache/tools/ant/launch/LocatorTest.java View File

@@ -27,6 +27,8 @@ import org.apache.tools.ant.taskdefs.condition.Os;
public class LocatorTest extends TestCase {
private boolean windows;
private boolean unix;
private static final String LAUNCHER_JAR = "//morzine/slo/Java/Apache/ant/lib/ant-launcher.jar";
private static final String SHARED_JAR_URI = "jar:file:"+ LAUNCHER_JAR +"!/org/apache/tools/ant/launch/Launcher.class";

/**
* No-arg constructor to enable serialization. This method is not intended to be used by mere mortals without calling
@@ -35,7 +37,9 @@ public class LocatorTest extends TestCase {
public LocatorTest() {
}

/** Constructs a test case with the given name. */
/** Constructs a test case with the given name.
* @param name
*/
public LocatorTest(String name) {
super(name);
}
@@ -63,6 +67,7 @@ public class LocatorTest extends TestCase {
* @param uri uri to parse
* @param expectedUnix unix string (or null to skip that test)
* @param expectedDos DOS string (or null to skip that test)
* @return the resolved string
*/
private String resolveTo(String uri, String expectedUnix, String expectedDos) {
String result = resolve(uri);
@@ -71,8 +76,15 @@ public class LocatorTest extends TestCase {
return result;
}

private void assertResolved(String uri, String expectedResult, String result, boolean condition) {
if (condition && expectedResult != null && expectedResult.length() > 0) {
/**
* Assert something resolved
* @param uri original URI
* @param expectedResult what we expected
* @param result what we got
* @param enabled is the test enabled?
*/
private void assertResolved(String uri, String expectedResult, String result, boolean enabled) {
if (enabled && expectedResult != null && expectedResult.length() > 0) {
assertEquals("Expected " + uri + " to resolve to \n" + expectedResult + "\n but got\n"
+ result + "\n", expectedResult, result);
}
@@ -83,7 +95,7 @@ public class LocatorTest extends TestCase {
* @param path filename with no directory separators
* @return the trailing filename
*/
private String assertResolves(String path) throws Exception {
private String assertResolves(String path) {
String asuri = new File(path).toURI().toASCIIString();
String fullpath = System.getProperty("user.dir") + File.separator + path;
String result = resolveTo(asuri, fullpath, fullpath);
@@ -127,6 +139,28 @@ public class LocatorTest extends TestCase {
"C:\\Program Files\\Ant\\lib");
}

/**
* Bug 42275; Ant failing to run off a remote share
* @throws Throwable if desired
*/
public void testAntOnRemoteShare() throws Throwable {
String resolved=Locator.fromJarURI(SHARED_JAR_URI);
assertResolved(SHARED_JAR_URI, LAUNCHER_JAR,resolved,true);
}

/**
* Bug 42275; Ant failing to run off a remote share
*
* @throws Throwable if desired
*/
public void testFileFromRemoteShare() throws Throwable {
String resolved = Locator.fromJarURI(SHARED_JAR_URI);
assertResolved(SHARED_JAR_URI, LAUNCHER_JAR, resolved, true);
File f=new File(resolved);
String path = f.getAbsolutePath();
assertTrue(path.indexOf("\\\\")==0);
}

public void testHttpURI() throws Exception {
String url = "http://ant.apache.org";
try {


Loading…
Cancel
Save