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"; 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. * The location of a per-user library directory.
* <p> * <p>
@@ -110,6 +115,9 @@ public class Launcher {
t.printStackTrace(System.err); t.printStackTrace(System.err);
} }
if (exitCode != 0) { if (exitCode != 0) {
if (launchDiag) {
System.out.println("Exit code: "+exitCode);
}
System.exit(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 * @param getJars if true and a path is a directory, add the jars in
* the directory to the path urls * the directory to the path urls
* @param libPathURLs the list of paths to add to * @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) private void addPath(String path, boolean getJars, List libPathURLs)
throws MalformedURLException { throws MalformedURLException {
@@ -129,18 +138,21 @@ public class Launcher {
while (tokenizer.hasMoreElements()) { while (tokenizer.hasMoreElements()) {
String elementName = tokenizer.nextToken(); String elementName = tokenizer.nextToken();
File element = new File(elementName); File element = new File(elementName);
if (elementName.indexOf("%") != -1 && !element.exists()) {
if (elementName.indexOf('%') != -1 && !element.exists()) {
continue; continue;
} }
if (getJars && element.isDirectory()) { if (getJars && element.isDirectory()) {
// add any jars in the directory // add any jars in the directory
URL[] dirURLs = Locator.getLocationURLs(element); URL[] dirURLs = Locator.getLocationURLs(element);
for (int j = 0; j < dirURLs.length; ++j) { for (int j = 0; j < dirURLs.length; ++j) {
if (launchDiag) { System.out.println("adding library JAR: " + dirURLs[j]);}
libPathURLs.add(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 * @param args the command line arguments
* @return an exit code. As the normal ant main calls exit when it ends, * @return an exit code. As the normal ant main calls exit when it ends,
* this is for handling failures at bind-time * 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. * cannot be created.
* @throws LaunchException for launching problems
*/ */
private int run(String[] args) private int run(String[] args)
throws LaunchException, MalformedURLException { throws LaunchException, MalformedURLException {
@@ -168,12 +181,12 @@ public class Launcher {


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


if (!antHome.exists()) { if (!antHome.exists()) {
throw new LaunchException("Ant home is set incorrectly or " 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(); List libPaths = new ArrayList();
@@ -202,6 +215,8 @@ public class Launcher {
cpString = args[++i]; cpString = args[++i];
} else if (args[i].equals("--nouserlib") || args[i].equals("-nouserlib")) { } else if (args[i].equals("--nouserlib") || args[i].equals("-nouserlib")) {
noUserLib = true; noUserLib = true;
} else if (args[i].equals("--launchdiag")) {
launchDiag = true;
} else if (args[i].equals("--noclasspath") || args[i].equals("-noclasspath")) { } else if (args[i].equals("--noclasspath") || args[i].equals("-noclasspath")) {
noClassPath = true; noClassPath = true;
} else if (args[i].equals("-main")) { } 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 //decide whether to copy the existing arg set, or
//build a new one from the list of all args excluding the special //build a new one from the list of all args excluding the special
//operations that only we handle //operations that only we handle
@@ -229,8 +248,10 @@ public class Launcher {
URL[] systemURLs = getSystemURLs(jarDir); URL[] systemURLs = getSystemURLs(jarDir);
URL[] userURLs = noUserLib ? new URL[0] : getUserURLs(); URL[] userURLs = noUserLib ? new URL[0] : getUserURLs();


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


// now update the class.path property // now update the class.path property
StringBuffer baseClassPath StringBuffer baseClassPath
@@ -245,12 +266,13 @@ public class Launcher {
baseClassPath.append(Locator.fromURI(jars[i].toString())); 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); URLClassLoader loader = new URLClassLoader(jars);
Thread.currentThread().setContextClassLoader(loader); Thread.currentThread().setContextClassLoader(loader);
Class mainClass = null; Class mainClass = null;
int exitCode = 0; int exitCode = 0;
Throwable thrown=null;
try { try {
mainClass = loader.loadClass(mainClassname); mainClass = loader.loadClass(mainClassname);
AntMain main = (AntMain) mainClass.newInstance(); AntMain main = (AntMain) mainClass.newInstance();
@@ -261,9 +283,20 @@ public class Launcher {
File mainJar = Locator.getClassSource(mainClass); File mainJar = Locator.getClassSource(mainClass);
System.err.println( System.err.println(
"Location of this class " + mainJar); "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) { } catch (Throwable t) {
t.printStackTrace(System.err); 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; exitCode = EXIT_CODE_ERROR;
} }
return exitCode; return exitCode;
@@ -275,6 +308,7 @@ public class Launcher {
* @param cpString the classpath string * @param cpString the classpath string
* @param libPaths the list of -lib entries. * @param libPaths the list of -lib entries.
* @return an array of URLs. * @return an array of URLs.
* @throws MalformedURLException if the URLs cannot be created.
*/ */
private URL[] getLibPathURLs(String cpString, List libPaths) private URL[] getLibPathURLs(String cpString, List libPaths)
throws MalformedURLException { throws MalformedURLException {
@@ -296,6 +330,9 @@ public class Launcher {
* Get the jar files in ANT_HOME/lib. * Get the jar files in ANT_HOME/lib.
* determine ant library directory for system jars: use property * determine ant library directory for system jars: use property
* or default using location of ant-launcher.jar * 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 { private URL[] getSystemURLs(File antLauncherDir) throws MalformedURLException {
File antLibDir = null; File antLibDir = null;
@@ -305,13 +342,15 @@ public class Launcher {
} }
if ((antLibDir == null) || !antLibDir.exists()) { if ((antLibDir == null) || !antLibDir.exists()) {
antLibDir = antLauncherDir; antLibDir = antLauncherDir;
System.setProperty(ANTLIBDIR_PROPERTY, antLibDir.getAbsolutePath());
setProperty(ANTLIBDIR_PROPERTY, antLibDir.getAbsolutePath());
} }
return Locator.getLocationURLs(antLibDir); return Locator.getLocationURLs(antLibDir);
} }


/** /**
* Get the jar files in user.home/.ant/lib * 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 { private URL[] getUserURLs() throws MalformedURLException {
File userLibDir File userLibDir
@@ -347,4 +386,22 @@ public class Launcher {
} }
return jars; 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(); String u = url.toString();
try { try {
if (u.startsWith("jar:file:")) { 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:")) { } else if (u.startsWith("file:")) {
int tail = u.indexOf(resource); int tail = u.indexOf(resource);
String dirName = u.substring(0, tail); String dirName = u.substring(0, tail);
@@ -160,6 +158,8 @@ public final class Locator {
return null; return null;
} }




/** /**
* Constructs a file path from a <code>file:</code> URI. * Constructs a file path from a <code>file:</code> URI.
* *
@@ -238,13 +238,16 @@ public final class Locator {
return null; 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 * @param uri uri to expand
* @return the decoded URI * @return the decoded URI
* @since Ant1.7.1 * @since Ant1.7.1
*/ */
static String fromURIJava13(String uri) {
public static String fromURIJava13(String uri) {
// Fallback method for Java 1.3 or earlier. // Fallback method for Java 1.3 or earlier.


URL url = null; URL url = null;
@@ -273,10 +276,14 @@ public final class Locator {
String path = null; String path = null;
try { try {
path = decodeUri(uri); 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"); 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) { } catch (UnsupportedEncodingException exc) {
// not sure whether this is clean, but this method is // not sure whether this is clean, but this method is
@@ -288,6 +295,19 @@ public final class Locator {
return path; 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. * Decodes an Uri with % characters.
* The URI is escaped * 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 { public class LocatorTest extends TestCase {
private boolean windows; private boolean windows;
private boolean unix; 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 * 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() { public LocatorTest() {
} }


/** Constructs a test case with the given name. */
/** Constructs a test case with the given name.
* @param name
*/
public LocatorTest(String name) { public LocatorTest(String name) {
super(name); super(name);
} }
@@ -63,6 +67,7 @@ public class LocatorTest extends TestCase {
* @param uri uri to parse * @param uri uri to parse
* @param expectedUnix unix string (or null to skip that test) * @param expectedUnix unix string (or null to skip that test)
* @param expectedDos DOS 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) { private String resolveTo(String uri, String expectedUnix, String expectedDos) {
String result = resolve(uri); String result = resolve(uri);
@@ -71,8 +76,15 @@ public class LocatorTest extends TestCase {
return result; 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" assertEquals("Expected " + uri + " to resolve to \n" + expectedResult + "\n but got\n"
+ result + "\n", expectedResult, result); + result + "\n", expectedResult, result);
} }
@@ -83,7 +95,7 @@ public class LocatorTest extends TestCase {
* @param path filename with no directory separators * @param path filename with no directory separators
* @return the trailing filename * @return the trailing filename
*/ */
private String assertResolves(String path) throws Exception {
private String assertResolves(String path) {
String asuri = new File(path).toURI().toASCIIString(); String asuri = new File(path).toURI().toASCIIString();
String fullpath = System.getProperty("user.dir") + File.separator + path; String fullpath = System.getProperty("user.dir") + File.separator + path;
String result = resolveTo(asuri, fullpath, fullpath); String result = resolveTo(asuri, fullpath, fullpath);
@@ -127,6 +139,28 @@ public class LocatorTest extends TestCase {
"C:\\Program Files\\Ant\\lib"); "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 { public void testHttpURI() throws Exception {
String url = "http://ant.apache.org"; String url = "http://ant.apache.org";
try { try {


Loading…
Cancel
Save