diff --git a/build.xml b/build.xml
index cf01d3c06..0b91775b5 100644
--- a/build.xml
+++ b/build.xml
@@ -18,12 +18,31 @@
+
-
+
+
+
+
+
+
+
+
+
+
+
@@ -33,6 +52,8 @@
+
+
@@ -90,7 +103,8 @@
-
+
+
@@ -113,8 +127,6 @@
-
-
+
+
+
+
+
+
+
+
@@ -675,6 +731,7 @@
+
diff --git a/src/main/org/apache/tools/ant/Main.java b/src/main/org/apache/tools/ant/Main.java
index 802cde583..bd4d0e133 100644
--- a/src/main/org/apache/tools/ant/Main.java
+++ b/src/main/org/apache/tools/ant/Main.java
@@ -66,6 +66,8 @@ import java.util.Vector;
import org.apache.tools.ant.input.DefaultInputHandler;
import org.apache.tools.ant.input.InputHandler;
import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.launch.AntMain;
+
/**
* Command line entry point into Ant. This class is entered via the
@@ -79,7 +81,7 @@ import org.apache.tools.ant.util.JavaEnvUtils;
*
* @author duncan@x180.com
*/
-public class Main {
+public class Main implements AntMain {
/** The default build file name. */
public static final String DEFAULT_BUILD_FILENAME = "build.xml";
@@ -175,11 +177,25 @@ public class Main {
*/
public static void start(String[] args, Properties additionalUserProperties,
ClassLoader coreLoader) {
- Main m = null;
+ Main m = new Main();
+ m.startAnt(args, additionalUserProperties, coreLoader);
+ }
+
+ /**
+ * Start Ant
+ * @param args command line args
+ * @param additionalUserProperties properties to set beyond those that
+ * may be specified on the args list
+ * @param coreLoader - not used
+ *
+ * @since Ant 1.6
+ */
+ public void startAnt(String[] args, Properties additionalUserProperties,
+ ClassLoader coreLoader) {
try {
Diagnostics.validateVersion();
- m = new Main(args);
+ processArgs(args);
} catch (Throwable exc) {
handleLogfile();
printMessage(exc);
@@ -191,17 +207,17 @@ public class Main {
e.hasMoreElements();) {
String key = (String) e.nextElement();
String property = additionalUserProperties.getProperty(key);
- m.definedProps.put(key, property);
+ definedProps.put(key, property);
}
}
// expect the worst
int exitCode = 1;
try {
- m.runBuild(coreLoader);
+ runBuild(coreLoader);
exitCode = 0;
} catch (BuildException be) {
- if (m.err != System.err) {
+ if (err != System.err) {
printMessage(be);
}
} catch (Throwable exc) {
@@ -248,6 +264,13 @@ public class Main {
start(args, null, null);
}
+ /**
+ * Constructor used when creating Main for later arg processing
+ * and startup
+ */
+ public Main() {
+ }
+
/**
* Sole constructor, which parses and deals with command line
* arguments.
@@ -258,6 +281,17 @@ public class Main {
* or is a directory.
*/
protected Main(String[] args) throws BuildException {
+ processArgs(args);
+ }
+
+ /**
+ * Process command line arguments
+ *
+ * @param args the command line arguments.
+ *
+ * @since Ant 1.6
+ */
+ private void processArgs(String[] args) {
String searchForThis = null;
PrintStream logTo = null;
@@ -656,8 +690,8 @@ public class Main {
try {
BuildListener listener =
(BuildListener) Class.forName(className).newInstance();
- if ( project != null ) {
- project.setProjectReference( listener );
+ if (project != null) {
+ project.setProjectReference(listener);
}
project.addBuildListener(listener);
} catch (Throwable exc) {
@@ -670,6 +704,8 @@ public class Main {
/**
* Creates the InputHandler and adds it to the project.
*
+ * @param project the project instance.
+ *
* @exception BuildException if a specified InputHandler
* implementation could not be loaded.
*/
@@ -681,8 +717,8 @@ public class Main {
try {
handler = (InputHandler)
(Class.forName(inputHandlerClassname).newInstance());
- if ( project != null ) {
- project.setProjectReference( handler );
+ if (project != null) {
+ project.setProjectReference(handler);
}
} catch (ClassCastException e) {
String msg = "The specified input handler class "
@@ -713,7 +749,8 @@ public class Main {
BuildLogger logger = null;
if (loggerClassname != null) {
try {
- logger = (BuildLogger) (Class.forName(loggerClassname).newInstance());
+ Class loggerClass = Class.forName(loggerClassname);
+ logger = (BuildLogger) (loggerClass.newInstance());
} catch (ClassCastException e) {
System.err.println("The specified logger class "
+ loggerClassname
@@ -918,6 +955,8 @@ public class Main {
* Writes a formatted list of target names to System.out
* with an optional description.
*
+ *
+ * @param project the project instance.
* @param names The names to be printed.
* Must not be null
.
* @param descriptions The associated target descriptions.
diff --git a/src/main/org/apache/tools/ant/launch/AntMain.java b/src/main/org/apache/tools/ant/launch/AntMain.java
new file mode 100644
index 000000000..fe2ea8317
--- /dev/null
+++ b/src/main/org/apache/tools/ant/launch/AntMain.java
@@ -0,0 +1,79 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2003 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.launch;
+
+import java.util.Properties;
+
+/**
+ * Interface used to bridge to the actual Main class without any
+ * messy reflection
+ *
+ * @author Conor MacNeill
+ * @since Ant 1.6
+ */
+public interface AntMain {
+ /**
+ * Start Ant.
+ *
+ * @param args command line args
+ * @param additionalUserProperties properties to set beyond those that
+ * may be specified on the args list
+ * @param coreLoader - not used
+ *
+ * @since Ant 1.6
+ */
+ void startAnt(String[] args, Properties additionalUserProperties,
+ ClassLoader coreLoader);
+}
+
diff --git a/src/main/org/apache/tools/ant/launch/Launcher.java b/src/main/org/apache/tools/ant/launch/Launcher.java
new file mode 100644
index 000000000..019ba04ee
--- /dev/null
+++ b/src/main/org/apache/tools/ant/launch/Launcher.java
@@ -0,0 +1,168 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2003 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.launch;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.MalformedURLException;
+import java.io.File;
+
+/**
+ * This is a launcher for Ant.
+ *
+ * @author Conor MacNeill
+ * @since Ant 1.6
+ */
+public class Launcher {
+ /** The Ant Home property */
+ public static final String ANTHOME_PROPERTY = "ant.home";
+
+ /** The location of a per-user library directory */
+ public static final String USER_LIBDIR = ".ant/lib";
+
+ /** The startup class that is to be run */
+ public static final String MAIN_CLASS = "org.apache.tools.ant.Main";
+
+ /**
+ * Entry point for starting command line Ant
+ *
+ * @param args commandline arguments
+ */
+ public static void main(String[] args) {
+ try {
+ Launcher launcher = new Launcher();
+ launcher.run(args);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+
+ /**
+ * Run the launcher to launch Ant
+ *
+ * @param args the command line arguments
+ *
+ * @exception MalformedURLException if the URLs required for the classloader
+ * cannot be created.
+ */
+ private void run(String[] args) throws MalformedURLException {
+ String antHomeProperty = System.getProperty(ANTHOME_PROPERTY);
+ File antHome = null;
+
+ URL launchJarURL = Locator.getClassLocationURL(getClass());
+ File jarDir = new File(launchJarURL.getFile()).getParentFile();
+
+ if (antHomeProperty != null) {
+ antHome = new File(antHomeProperty);
+ }
+
+ if (antHome == null || !antHome.exists()) {
+ URL antHomeURL = new URL(launchJarURL, "..");
+ antHome = new File(antHomeURL.getFile());
+ System.setProperty(ANTHOME_PROPERTY, antHome.getAbsolutePath());
+ }
+
+ if (!antHome.exists()) {
+ throw new IllegalStateException("Ant home is set incorrectly or "
+ + "ant could not be located");
+ }
+
+
+ // Now try and find JAVA_HOME
+ File toolsJar = Locator.getToolsJar();
+
+ URL[] systemJars = Locator.getLocationURLs(jarDir);
+
+ File userLibDir
+ = new File(System.getProperty("user.home"), USER_LIBDIR);
+ URL[] userJars = Locator.getLocationURLs(userLibDir);
+
+
+ int numJars = userJars.length + systemJars.length;
+ if (toolsJar != null) {
+ numJars++;
+ }
+ URL[] jars = new URL[numJars];
+ System.arraycopy(userJars, 0, jars, 0, userJars.length);
+ System.arraycopy(systemJars, 0, jars, userJars.length,
+ systemJars.length);
+
+ if (toolsJar != null) {
+ jars[jars.length - 1] = toolsJar.toURL();
+ }
+
+
+ // now update the class.path property
+ StringBuffer baseClassPath
+ = new StringBuffer(System.getProperty("java.class.path"));
+
+ for (int i = 0; i < jars.length; ++i) {
+ baseClassPath.append(File.pathSeparatorChar);
+ baseClassPath.append(jars[i].getFile());
+ }
+
+ System.setProperty("java.class.path", baseClassPath.toString());
+
+ URLClassLoader loader = new URLClassLoader(jars);
+ try {
+ Class mainClass = loader.loadClass(MAIN_CLASS);
+ AntMain main = (AntMain) mainClass.newInstance();
+ main.startAnt(args, null, null);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+}
+
diff --git a/src/main/org/apache/tools/ant/launch/Locator.java b/src/main/org/apache/tools/ant/launch/Locator.java
new file mode 100644
index 000000000..44163120e
--- /dev/null
+++ b/src/main/org/apache/tools/ant/launch/Locator.java
@@ -0,0 +1,226 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2003 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.launch;
+
+import java.net.MalformedURLException;
+
+import java.net.URL;
+import java.io.File;
+import java.io.FilenameFilter;
+
+/**
+ * The Locator is a utility class which is used to find certain items
+ * in the environment
+ *
+ * @author Conor MacNeill
+ * @since Ant 1.6
+ */
+public class Locator {
+ /**
+ * Get the URL for the given class's load location.
+ *
+ * @param theClass the class whose load URL is desired.
+ * @return a URL which identifies the component from which this class
+ * was loaded.
+ * @throws MalformedURLException if the class' URL cannot be
+ * constructed.
+ */
+ public static URL getClassLocationURL(Class theClass)
+ throws MalformedURLException {
+ String className = theClass.getName().replace('.', '/') + ".class";
+ URL classRawURL = theClass.getClassLoader().getResource(className);
+
+ String fileComponent = classRawURL.getFile();
+ if (classRawURL.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);
+ }
+
+ return new URL("file:" + fileComponent);
+ } else if (classRawURL.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);
+ }
+
+ return new URL(fileComponent);
+ } else {
+ // its running out of something besides a jar.
+ // We just return the Raw URL as a best guess
+ return classRawURL;
+ }
+ }
+
+ /**
+ * Get the URL necessary to load the Sun compiler tools. If the classes
+ * are available to this class, then no additional URL is required and
+ * null is returned. This may be because the classes are explcitly in the
+ * class path or provided by the JVM directly
+ *
+ * @return the tools jar as a File if required, null otherwise
+ */
+ public static File getToolsJar() {
+ // firstly check if the tols jar is alreayd n the classpath
+ boolean toolsJarAvailable = false;
+
+ try {
+ // just check whether this throws an exception
+ Class.forName("com.sun.tools.javac.Main");
+ toolsJarAvailable = true;
+ } catch (Exception e) {
+ try {
+ Class.forName("sun.tools.javac.Main");
+ toolsJarAvailable = true;
+ } catch (Exception e2) {
+ // ignore
+ }
+ }
+
+ if (toolsJarAvailable) {
+ return null;
+ }
+
+ // couldn't find compiler - try to find tools.jar
+ // based on java.home setting
+ String javaHome = System.getProperty("java.home");
+ if (javaHome.endsWith("jre")) {
+ javaHome = javaHome.substring(0, javaHome.length() - 4);
+ }
+ File toolsJar = new File(javaHome + "/lib/tools.jar");
+ if (!toolsJar.exists()) {
+ System.out.println("Unable to locate tools.jar. "
+ + "Expected to find it in " + toolsJar.getPath());
+ return null;
+ }
+ return toolsJar;
+ }
+
+ /**
+ * Get an array or URLs representing all of the jar files in the
+ * given location. If the location is a file, it is returned as the only
+ * element of the array. If the location is a directory, it is scanned for
+ * jar files
+ *
+ * @param location the location to scan for Jars
+ *
+ * @return an array of URLs for all jars in the given location.
+ *
+ * @exception MalformedURLException if the URLs for the jars cannot be
+ * formed
+ */
+ public static URL[] getLocationURLs(File location)
+ throws MalformedURLException {
+ return getLocationURLs(location, new String[]{".jar"});
+ }
+
+ /**
+ * Get an array or URLs representing all of the files of a given set of
+ * extensions in the given location. If the location is a file, it is
+ * returned as the only element of the array. If the location is a
+ * directory, it is scanned for matching files
+ *
+ * @param location the location to scan for files
+ * @param extensions an array of extension that are to match in the
+ * directory search
+ *
+ * @return an array of URLs of matching files
+ * @exception MalformedURLException if the URLs for the files cannot be
+ * formed
+ */
+ public static URL[] getLocationURLs(File location,
+ final String[] extensions)
+ throws MalformedURLException {
+ URL[] urls = new URL[0];
+
+ if (!location.exists()) {
+ return urls;
+ }
+
+ if (!location.isDirectory()) {
+ urls = new URL[1];
+ String path = location.getPath();
+ for (int i = 0; i < extensions.length; ++i) {
+ if (path.endsWith(extensions[i])) {
+ urls[0] = location.toURL();
+ break;
+ }
+ }
+ return urls;
+ }
+
+ File[] matches = location.listFiles(
+ new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ for (int i = 0; i < extensions.length; ++i) {
+ if (name.endsWith(extensions[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+ });
+
+ urls = new URL[matches.length];
+ for (int i = 0; i < matches.length; ++i) {
+ urls[i] = matches[i].toURL();
+ }
+ return urls;
+ }
+}
+