diff --git a/proposal/mutant/src/main/org/apache/ant/core/support/AntClassLoader.java b/proposal/mutant/src/main/org/apache/ant/core/support/AntClassLoader.java
index 4b0b0f8f4..697da33af 100644
--- a/proposal/mutant/src/main/org/apache/ant/core/support/AntClassLoader.java
+++ b/proposal/mutant/src/main/org/apache/ant/core/support/AntClassLoader.java
@@ -59,7 +59,7 @@ import java.net.*;
import java.io.*;
/**
- * The AntClassLoader is a type of URL classloader which reverse the standard
+ * The AntClassLoader is a type of URL classloader which reverses the standard
* lookup order to load things from the URLs first and then to use the parent class
* loader only if the class does not exist in the URLs.
*
diff --git a/src/main/org/apache/tools/ant/AntClassLoader.java b/src/main/org/apache/tools/ant/AntClassLoader.java
index f9dc88dd6..42d138d27 100644
--- a/src/main/org/apache/tools/ant/AntClassLoader.java
+++ b/src/main/org/apache/tools/ant/AntClassLoader.java
@@ -70,7 +70,7 @@ import org.apache.tools.ant.types.Path;
* @author Conor MacNeill
* @author Jesse Glick
*/
-public class AntClassLoader extends ClassLoader implements BuildListener {
+public class AntClassLoader extends ClassLoader implements BuildListener {
/**
* An enumeration of all resources of a given name found within the
@@ -90,11 +90,6 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
*/
private String resourceName;
- /**
- * The array of classpath elements.
- */
- private String[] pathElements;
-
/**
* The index of the next classpath element to search.
*/
@@ -115,7 +110,6 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
*/
ResourceEnumeration(String name) {
this.resourceName = name;
- this.pathElements = AntClassLoader.this.classpath.list();
this.pathElementsIndex = 0;
findNextResource();
}
@@ -150,13 +144,13 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
*/
private void findNextResource() {
URL url = null;
- while ((this.pathElementsIndex < this.pathElements.length) &&
+ while ((pathElementsIndex < pathComponents.size()) &&
(url == null)) {
try {
- File pathComponent = AntClassLoader.this.project.resolveFile(
- (String)this.pathElements[this.pathElementsIndex]);
+ File pathComponent
+ = (File)pathComponents.elementAt(pathElementsIndex);
url = getResourceURL(pathComponent, this.resourceName);
- this.pathElementsIndex++;
+ pathElementsIndex++;
}
catch (BuildException e) {
// ignore path elements which are not valid relative to the project
@@ -172,9 +166,9 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
static private final int BUFFER_SIZE = 1024;
/**
- * The classpath that is to be used when loading classes using this class loader.
- */
- private Path classpath;
+ * The components of the classpath that the classloader searches for classes
+ */
+ Vector pathComponents = new Vector();
/**
* The project to which this class loader belongs.
@@ -182,28 +176,33 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
private Project project;
/**
- * Indicates whether the system class loader should be
+ * Indicates whether the parent class loader should be
* consulted before trying to load with this class loader.
*/
- private boolean systemFirst = true;
+ private boolean parentFirst = true;
/**
- * These are the package roots that are to be loaded by the system class loader
- * regardless of whether the system class loader is being searched first or not.
+ * These are the package roots that are to be loaded by the parent class loader
+ * regardless of whether the parent class loader is being searched first or not.
*/
private Vector systemPackages = new Vector();
/**
* These are the package roots that are to be loaded by this class loader
- * regardless of whether the system class loader is being searched first or not.
+ * regardless of whether the parent class loader is being searched first or not.
*/
private Vector loaderPackages = new Vector();
/**
* This flag indicates that the classloader will ignore the base
- * classloader if it can;t find a class.
+ * classloader if it can't find a class.
*/
private boolean ignoreBase = false;
+
+ /**
+ * The parent class loader, if one is given or can be determined
+ */
+ private ClassLoader parent = null;
private static Method getProtectionDomain = null;
private static Method defineClassProtectionDomain = null;
@@ -227,24 +226,75 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
* determined by the value of ${build.sysclasspath}
*/
public AntClassLoader(Project project, Path classpath) {
+ parent = AntClassLoader.class.getClassLoader();
this.project = project;
- this.project.addBuildListener(this);
- this.classpath = classpath.concatSystemClasspath("ignore");
+ project.addBuildListener(this);
+ if (classpath != null) {
+ Path actualClasspath = classpath.concatSystemClasspath("ignore");
+ String[] pathElements = actualClasspath.list();
+ for (int i = 0; i < pathElements.length; ++i) {
+ try {
+ addPathElement((String)pathElements[i]);
+ }
+ catch (BuildException e) {
+ // ignore path elements which are invalid relative to the project
+ }
+ }
+ }
}
-
+
/**
* Create a classloader for the given project using the classpath given.
*
* @param project the project to which this classloader is to belong.
* @param classpath the classpath to use to load the classes.
*/
- public AntClassLoader(Project project, Path classpath, boolean systemFirst) {
+ public AntClassLoader(ClassLoader parent, Project project, Path classpath,
+ boolean parentFirst) {
this(project, classpath);
- this.systemFirst = systemFirst;
+ if (parent != null) {
+ this.parent = parent;
+ }
+ this.parentFirst = parentFirst;
addSystemPackageRoot("java");
addSystemPackageRoot("javax");
}
+ /**
+ * Create an empty class loader
+ *
+ */
+ public AntClassLoader(ClassLoader parent, boolean parentFirst) {
+ if (parent != null) {
+ this.parent = parent;
+ }
+ else {
+ parent = AntClassLoader.class.getClassLoader();
+ }
+ project = null;
+ this.parentFirst = parentFirst;
+ }
+
+ protected void log(String message, int priority) {
+ if (project != null) {
+ project.log(message, priority);
+ }
+// else {
+// System.out.println(message);
+// }
+ }
+
+ /**
+ * Add an element to the classpath to be searched
+ *
+ */
+ public void addPathElement(String pathElement) throws BuildException {
+ File pathComponent
+ = project != null ? project.resolveFile(pathElement)
+ : new File(pathElement);
+ pathComponents.addElement(pathComponent);
+ }
+
/**
* Set this classloader to run in isolated mode. In isolated mode, classes not
* found on the given classpath will not be referred to the base class loader
@@ -272,7 +322,7 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
/**
* Add a package root to the list of packages which must be loaded on the
- * system loader.
+ * parent loader.
*
* All subpackages are also included.
*
@@ -298,7 +348,7 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
/**
* Load a class through this class loader even if that class is available on the
- * system classpath.
+ * parent classpath.
*
* This ensures that any classes which are loaded by the returned class will use this
* classloader.
@@ -311,7 +361,8 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
* this loader's classpath.
*/
public Class forceLoadClass(String classname) throws ClassNotFoundException {
- project.log("force loading " + classname, Project.MSG_DEBUG);
+ log("force loading " + classname, Project.MSG_DEBUG);
+
Class theClass = findLoadedClass(classname);
if (theClass == null) {
@@ -322,10 +373,10 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
}
/**
- * Load a class through this class loader but defer to the system class loader
+ * Load a class through this class loader but defer to the parent class loader
*
* This ensures that instances of the returned class will be compatible with instances which
- * which have already been loaded on the system loader.
+ * which have already been loaded on the parent loader.
*
* @param classname the classname to be loaded.
*
@@ -335,7 +386,8 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
* this loader's classpath.
*/
public Class forceLoadSystemClass(String classname) throws ClassNotFoundException {
- project.log("force system loading " + classname, Project.MSG_DEBUG);
+ log("force system loading " + classname, Project.MSG_DEBUG);
+
Class theClass = findLoadedClass(classname);
if (theClass == null) {
@@ -356,38 +408,38 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
public InputStream getResourceAsStream(String name) {
InputStream resourceStream = null;
- if (isSystemFirst(name)) {
+ if (isParentFirst(name)) {
resourceStream = loadBaseResource(name);
if (resourceStream != null) {
- project.log("ResourceStream for " + name
- + " loaded from system loader", Project.MSG_DEBUG);
+ log("ResourceStream for " + name
+ + " loaded from parent loader", Project.MSG_DEBUG);
} else {
resourceStream = loadResource(name);
if (resourceStream != null) {
- project.log("ResourceStream for " + name
- + " loaded from ant loader", Project.MSG_DEBUG);
+ log("ResourceStream for " + name
+ + " loaded from ant loader", Project.MSG_DEBUG);
}
}
}
else {
resourceStream = loadResource(name);
if (resourceStream != null) {
- project.log("ResourceStream for " + name
- + " loaded from ant loader", Project.MSG_DEBUG);
+ log("ResourceStream for " + name
+ + " loaded from ant loader", Project.MSG_DEBUG);
} else {
resourceStream = loadBaseResource(name);
if (resourceStream != null) {
- project.log("ResourceStream for " + name
- + " loaded from system loader", Project.MSG_DEBUG);
+ log("ResourceStream for " + name
+ + " loaded from parent loader", Project.MSG_DEBUG);
}
}
}
if (resourceStream == null) {
- project.log("Couldn't load ResourceStream for " + name,
- Project.MSG_WARN);
+ log("Couldn't load ResourceStream for " + name,
+ Project.MSG_WARN);
}
return resourceStream;
@@ -408,30 +460,22 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
// class we want.
InputStream stream = null;
- String[] pathElements = classpath.list();
- for (int i = 0; i < pathElements.length && stream == null; ++i) {
- try {
- File pathComponent = project.resolveFile((String)pathElements[i]);
- stream = getResourceStream(pathComponent, name);
- }
- catch (BuildException e) {
- // ignore path elements which are invalid relative to the project
- }
+ for (Enumeration e = pathComponents.elements(); e.hasMoreElements() && stream == null; ) {
+ File pathComponent = (File)e.nextElement();
+ stream = getResourceStream(pathComponent, name);
}
-
return stream;
}
/**
- * Find a system resource (which should be loaded from the same classloader as the Ant core).
+ * Find a system resource (which should be loaded from the parent classloader).
*/
private InputStream loadBaseResource(String name) {
- ClassLoader base = AntClassLoader.class.getClassLoader();
- if (base == null) {
+ if (parent == null) {
return getSystemResourceAsStream(name);
}
else {
- return base.getResourceAsStream(name);
+ return parent.getResourceAsStream(name);
}
}
@@ -485,22 +529,23 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
}
}
catch (Exception e) {
- e.printStackTrace();
+ log("Ignoring Exception " + e.getClass().getName() + ": " + e.getMessage() +
+ " reading resource " + resourceName + " from " + file, Project.MSG_VERBOSE);
}
return null;
}
- private boolean isSystemFirst(String resourceName) {
+ private boolean isParentFirst(String resourceName) {
// default to the global setting and then see
// if this class belongs to a package which has been
- // designated to use a specific loader first (this one or the system one)
- boolean useSystemFirst = systemFirst;
+ // designated to use a specific loader first (this one or the parent one)
+ boolean useParentFirst = parentFirst;
for (Enumeration e = systemPackages.elements(); e.hasMoreElements();) {
String packageName = (String)e.nextElement();
if (resourceName.startsWith(packageName)) {
- useSystemFirst = true;
+ useParentFirst = true;
break;
}
}
@@ -508,12 +553,12 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
for (Enumeration e = loaderPackages.elements(); e.hasMoreElements();) {
String packageName = (String)e.nextElement();
if (resourceName.startsWith(packageName)) {
- useSystemFirst = false;
+ useParentFirst = false;
break;
}
}
- return useSystemFirst;
+ return useParentFirst;
}
@@ -536,45 +581,40 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
// we need to search the components of the path to see if we can find the
// class we want.
URL url = null;
- if (isSystemFirst(name)) {
- url = super.getResource(name);
+ if (isParentFirst(name)) {
+ url = (parent == null) ? super.getResource(name) : parent.getResource(name);
}
if (url != null) {
- project.log("Resource " + name + " loaded from system loader",
- Project.MSG_DEBUG);
+ log("Resource " + name + " loaded from parent loader",
+ Project.MSG_DEBUG);
} else {
// try and load from this loader if the parent either didn't find
// it or wasn't consulted.
- String[] pathElements = classpath.list();
- for (int i = 0; i < pathElements.length && url == null; ++i) {
- try {
- File pathComponent = project.resolveFile((String)pathElements[i]);
- url = getResourceURL(pathComponent, name);
- if (url != null) {
- project.log("Resource " + name
- + " loaded from ant loader",
- Project.MSG_DEBUG);
- }
- }
- catch (BuildException e) {
- // ignore path elements which are invalid relative to the project
+ for (Enumeration e = pathComponents.elements(); e.hasMoreElements() && url == null; ) {
+ File pathComponent = (File)e.nextElement();
+ url = getResourceURL(pathComponent, name);
+ if (url != null) {
+ log("Resource " + name
+ + " loaded from ant loader",
+ Project.MSG_DEBUG);
}
}
}
- if (url == null && !isSystemFirst(name)) {
+ if (url == null && !isParentFirst(name)) {
// this loader was first but it didn't find it - try the parent
- url = super.getResource(name);
+
+ url = (parent == null) ? super.getResource(name) : parent.getResource(name);
if (url != null) {
- project.log("Resource " + name + " loaded from system loader",
- Project.MSG_DEBUG);
+ log("Resource " + name + " loaded from parent loader",
+ Project.MSG_DEBUG);
}
}
if (url == null) {
- project.log("Couldn't load Resource " + name, Project.MSG_WARN);
+ log("Couldn't load Resource " + name, Project.MSG_WARN);
}
return url;
@@ -673,27 +713,27 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
return theClass;
}
- if (isSystemFirst(classname)) {
+ if (isParentFirst(classname)) {
try {
theClass = findBaseClass(classname);
- project.log("Class " + classname + " loaded from system loader", Project.MSG_DEBUG);
+ log("Class " + classname + " loaded from parent loader", Project.MSG_DEBUG);
}
catch (ClassNotFoundException cnfe) {
theClass = findClass(classname);
- project.log("Class " + classname + " loaded from ant loader", Project.MSG_DEBUG);
+ log("Class " + classname + " loaded from ant loader", Project.MSG_DEBUG);
}
}
else {
try {
theClass = findClass(classname);
- project.log("Class " + classname + " loaded from ant loader", Project.MSG_DEBUG);
+ log("Class " + classname + " loaded from ant loader", Project.MSG_DEBUG);
}
catch (ClassNotFoundException cnfe) {
if (ignoreBase) {
throw cnfe;
}
theClass = findBaseClass(classname);
- project.log("Class " + classname + " loaded from system loader", Project.MSG_DEBUG);
+ log("Class " + classname + " loaded from parent loader", Project.MSG_DEBUG);
}
}
@@ -705,12 +745,12 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
}
/**
- * Convert the class dot notation to a file system equivalent for
+ * Convert the class dot notation to a filesystem equivalent for
* searching purposes.
*
* @param classname the class name in dot format (ie java.lang.Integer)
*
- * @return the classname in file system format (ie java/lang/Integer.class)
+ * @return the classname in filesystem format (ie java/lang/Integer.class)
*/
private String getClassFilename(String classname) {
return classname.replace('.', '/') + ".class";
@@ -777,45 +817,34 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
* this loader's classpath.
*/
public Class findClass(String name) throws ClassNotFoundException {
- project.log("Finding class " + name, Project.MSG_DEBUG);
+ log("Finding class " + name, Project.MSG_DEBUG);
- try {
- return findClass(name, classpath);
- }
- catch (ClassNotFoundException e) {
- throw e;
- }
+ return findClassInComponents(name);
}
/**
* Find a class on the given classpath.
*/
- private Class findClass(String name, Path path) throws ClassNotFoundException {
+ private Class findClassInComponents(String name) throws ClassNotFoundException {
// we need to search the components of the path to see if we can find the
// class we want.
InputStream stream = null;
String classFilename = getClassFilename(name);
try {
- String[] pathElements = path.list();
- for (int i = 0; i < pathElements.length && stream == null; ++i) {
+ for (Enumeration e = pathComponents.elements(); e.hasMoreElements(); ) {
+ File pathComponent = (File)e.nextElement();
try {
- File pathComponent = project.resolveFile((String)pathElements[i]);
stream = getResourceStream(pathComponent, classFilename);
+ if (stream != null) {
+ return getClassFromStream(stream, name);
+ }
}
- catch (BuildException e) {
- // ignore invalid paths
+ catch (IOException ioe) {
+ log("Exception reading component " + pathComponent , Project.MSG_VERBOSE);
}
}
-
- if (stream == null) {
- throw new ClassNotFoundException();
- }
-
- return getClassFromStream(stream, name);
- }
- catch (IOException ioe) {
- ioe.printStackTrace();
+
throw new ClassNotFoundException();
}
finally {
@@ -832,19 +861,18 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
* Find a system class (which should be loaded from the same classloader as the Ant core).
*/
private Class findBaseClass(String name) throws ClassNotFoundException {
- ClassLoader base = AntClassLoader.class.getClassLoader();
- if (base == null) {
+ if (parent == null) {
return findSystemClass(name);
}
else {
- return base.loadClass(name);
+ return parent.loadClass(name);
}
}
public void buildStarted(BuildEvent event) {}
public void buildFinished(BuildEvent event) {
- classpath = null;
+ pathComponents = null;
project = null;
}
diff --git a/src/main/org/apache/tools/ant/Launcher.java b/src/main/org/apache/tools/ant/Launcher.java
new file mode 100644
index 000000000..6b14b98a5
--- /dev/null
+++ b/src/main/org/apache/tools/ant/Launcher.java
@@ -0,0 +1,201 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.lang.reflect.*;
+
+/**
+ * This is the Ant command line front end to end. This front end
+ * works out where ant is installed and loads the ant libraries before
+ * starting Ant proper.
+ *
+ * @author Conor MacNeill
+ */
+public class Launcher {
+ static private File determineAntHome11() {
+ String classpath = System.getProperty("java.class.path");
+ StringTokenizer tokenizer = new StringTokenizer(classpath, System.getProperty("path.separator"));
+ while (tokenizer.hasMoreTokens()) {
+ String path = tokenizer.nextToken();
+ if (path.endsWith("ant.jar")) {
+ File antJarFile = new File(path);
+ File libDirectory = new File(antJarFile.getParent());
+ File antHome = new File(libDirectory.getParent());
+ return antHome;
+ }
+ }
+ return null;
+ }
+
+ static private File determineAntHome(ClassLoader systemClassLoader) {
+ try {
+ String className = Launcher.class.getName().replace('.', '/') + ".class";
+ URL classResource = systemClassLoader.getResource(className);
+ String fileComponent = classResource.getFile();
+ if (classResource.getProtocol().equals("file")) {
+ // Class comes from a directory of class files rather than
+ // from a jar.
+ int classFileIndex = fileComponent.lastIndexOf(className);
+ if (classFileIndex != -1) {
+ fileComponent = fileComponent.substring(0, classFileIndex);
+ }
+ File classFilesDir = new File(fileComponent);
+ File buildDir = new File(classFilesDir.getParent());
+ File devAntHome = new File(buildDir.getParent());
+ return devAntHome;
+ }
+ else if (classResource.getProtocol().equals("jar")) {
+ // Class is coming from a jar. The file component of the URL
+ // is actually the URL of the jar file
+ int classSeparatorIndex = fileComponent.lastIndexOf("!");
+ if (classSeparatorIndex != -1) {
+ fileComponent = fileComponent.substring(0, classSeparatorIndex);
+ }
+ URL antJarURL = new URL(fileComponent);
+ File antJarFile = new File(antJarURL.getFile());
+ File libDirectory = new File(antJarFile.getParent());
+ File antHome = new File(libDirectory.getParent());
+ return antHome;
+ }
+ }
+ catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ static private void addDirJars(AntClassLoader classLoader, File jarDir) {
+ String[] fileList = jarDir.list(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".jar");
+ }
+ });
+
+ if (fileList != null) {
+ for (int i = 0; i < fileList.length; ++i) {
+ File jarFile = new File(jarDir, fileList[i]);
+ classLoader.addPathElement(jarFile.getAbsolutePath());
+ }
+ }
+ }
+
+ static private void addToolsJar(AntClassLoader antLoader) {
+ String javaHome = System.getProperty("java.home");
+ if (javaHome.endsWith("jre")) {
+ javaHome = javaHome.substring(0, javaHome.length() - 4);
+ }
+ System.out.println("Java home is " + javaHome);
+ File toolsJar = new File(javaHome, "lib/tools.jar");
+ if (!toolsJar.exists()) {
+ System.out.println("Unable to find tools.jar at " + toolsJar.getPath());
+ }
+ else {
+ antLoader.addPathElement(toolsJar.getAbsolutePath());
+ }
+ }
+
+
+ static public void main(String[] args) {
+ File antHome = null;
+ ClassLoader systemClassLoader = Launcher.class.getClassLoader();
+ if (systemClassLoader == null) {
+ antHome = determineAntHome11();
+ }
+ else {
+ antHome = determineAntHome(systemClassLoader);
+ }
+ if (antHome == null) {
+ System.err.println("Unable to determine ANT_HOME");
+ System.exit(1);
+ }
+
+ System.out.println("ANT_HOME is " + antHome);
+
+ // We now create the class loader with which we are going to launch ant
+ AntClassLoader antLoader = new AntClassLoader(systemClassLoader, false);
+
+ // need to find tools.jar
+ addToolsJar(antLoader);
+
+ // add everything in the lib directory to this classloader
+ File libDir = new File(antHome, "lib");
+ addDirJars(antLoader, libDir);
+
+ File optionalDir = new File(antHome, "lib/optional");
+ addDirJars(antLoader, optionalDir);
+
+ Properties launchProperties = new Properties();
+ launchProperties.put("ant.home", antHome.getAbsolutePath());
+
+ try {
+ Class mainClass = antLoader.loadClass("org.apache.tools.ant.Main");
+ antLoader.initializeClass(mainClass);
+
+ final Class[] param = {Class.forName("[Ljava.lang.String;"),
+ Properties.class, ClassLoader.class};
+ final Method startMethod = mainClass.getMethod("start", param);
+ final Object[] argument = {args, launchProperties, systemClassLoader};
+ startMethod.invoke(null, argument);
+ }
+ catch (Exception e) {
+ System.out.println("Exception running Ant: " + e.getClass().getName() + ": " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+}
+
diff --git a/src/main/org/apache/tools/ant/Main.java b/src/main/org/apache/tools/ant/Main.java
index 00a1a7cdb..e8512a240 100644
--- a/src/main/org/apache/tools/ant/Main.java
+++ b/src/main/org/apache/tools/ant/Main.java
@@ -129,13 +129,10 @@ public class Main {
}
/**
- * Command line entry point. This method kicks off the building
- * of a project object and executes a build using either a given
- * target or the default target.
- *
- * @param args Command line args.
+ * Entry point allowing for more options from other front ends
*/
- public static void main(String[] args) {
+ public static void start(String[] args, Properties additionalUserProperties,
+ ClassLoader systemLoader) {
Main m = null;
try {
@@ -145,8 +142,16 @@ public class Main {
System.exit(1);
}
+ if (additionalUserProperties != null) {
+ for (Enumeration e = additionalUserProperties.keys(); e.hasMoreElements(); ) {
+ String key = (String) e.nextElement();
+ String property = additionalUserProperties.getProperty(key);
+ m.definedProps.put(key, property);
+ }
+ }
+
try {
- m.runBuild();
+ m.runBuild(systemLoader);
System.exit(0);
} catch (BuildException be) {
if (m.err != System.err) {
@@ -158,6 +163,19 @@ public class Main {
System.exit(1);
}
}
+
+
+
+ /**
+ * Command line entry point. This method kicks off the building
+ * of a project object and executes a build using either a given
+ * target or the default target.
+ *
+ * @param args Command line args.
+ */
+ public static void main(String[] args) {
+ start(args, null, null);
+ }
protected Main(String[] args) throws BuildException {
@@ -364,7 +382,7 @@ public class Main {
/**
* Executes the build.
*/
- private void runBuild() throws BuildException {
+ private void runBuild(ClassLoader systemLoader) throws BuildException {
if (!readyToRun) {
return;
@@ -377,7 +395,8 @@ public class Main {
}
Project project = new Project();
-
+ project.setSystemLoader(systemLoader);
+
Throwable error = null;
try {
diff --git a/src/main/org/apache/tools/ant/Project.java b/src/main/org/apache/tools/ant/Project.java
index edc73c53c..fc2aff151 100644
--- a/src/main/org/apache/tools/ant/Project.java
+++ b/src/main/org/apache/tools/ant/Project.java
@@ -111,6 +111,9 @@ public class Project {
private static java.lang.reflect.Method setLastModified = null;
private static Object lockReflection = new Object();
+ /** The system classloader - may be null */
+ private ClassLoader systemLoader = null;
+
static {
// Determine the Java version by looking at available classes
@@ -212,6 +215,14 @@ public class Project {
}
}
+ public void setSystemLoader(ClassLoader systemLoader) {
+ this.systemLoader = systemLoader;
+ }
+
+ public ClassLoader getSystemLoader() {
+ return systemLoader;
+ }
+
public void addBuildListener(BuildListener listener) {
listeners.addElement(listener);
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java b/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
index 7fca86257..f85f5fec9 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
@@ -119,7 +119,8 @@ public class ExecuteJava {
if (classpath == null) {
target = Class.forName(classname);
} else {
- AntClassLoader loader = new AntClassLoader(project, classpath, false);
+ AntClassLoader loader
+ = new AntClassLoader(project.getSystemLoader(), project, classpath, false);
loader.setIsolated(true);
target = loader.forceLoadClass(classname);
AntClassLoader.initializeClass(target);
diff --git a/src/main/org/apache/tools/ant/taskdefs/Java.java b/src/main/org/apache/tools/ant/taskdefs/Java.java
index 2576a3bfe..5bab1d8a2 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Java.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Java.java
@@ -54,7 +54,6 @@
package org.apache.tools.ant.taskdefs;
-import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
index f3422792d..483ab368d 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
@@ -529,7 +529,7 @@ public class JUnitTask extends Task {
if (classpath != null) {
log("Using CLASSPATH " + classpath, Project.MSG_VERBOSE);
- cl = new AntClassLoader(project, classpath, false);
+ cl = new AntClassLoader(null, project, classpath, false);
// make sure the test will be accepted as a TestCase
cl.addSystemPackageRoot("junit");
// will cause trouble in JDK 1.1 if omitted