Home » apache-ant-1.7.1-src » org.apache.tools » ant » launch » [javadoc | source]
    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    *
   17    */
   18   package org.apache.tools.ant.launch;
   19   
   20   import java.net.URL;
   21   import java.net.URLClassLoader;
   22   import java.net.MalformedURLException;
   23   import java.io.File;
   24   import java.util.StringTokenizer;
   25   import java.util.List;
   26   import java.util.ArrayList;
   27   import java.util.Iterator;
   28   
   29   
   30   
   31   /**
   32    * This is a launcher for Ant.
   33    *
   34    * @since Ant 1.6
   35    */
   36   public class Launcher {
   37   
   38       /**
   39        * The Ant Home (installation) Directory property.
   40        * {@value}
   41        */
   42       public static final String ANTHOME_PROPERTY = "ant.home";
   43   
   44       /**
   45        * The Ant Library Directory property.
   46        * {@value}
   47        */
   48       public static final String ANTLIBDIR_PROPERTY = "ant.library.dir";
   49   
   50       /**
   51        * The directory name of the per-user ant directory.
   52        * {@value}
   53        */
   54       public static final String ANT_PRIVATEDIR = ".ant";
   55   
   56       /**
   57        * The name of a per-user library directory.
   58        * {@value}
   59        */
   60       public static final String ANT_PRIVATELIB = "lib";
   61   
   62       /**
   63        * The location of a per-user library directory.
   64        * <p>
   65        * It's value is the concatenation of {@link #ANT_PRIVATEDIR}
   66        * with {@link #ANT_PRIVATELIB}, with an appropriate file separator
   67        * in between. For example, on Unix, it's <code>.ant/lib</code>.
   68        */
   69       public static final String USER_LIBDIR =
   70           ANT_PRIVATEDIR + File.separatorChar + ANT_PRIVATELIB;
   71   
   72       /**
   73        * The startup class that is to be run.
   74        * {@value}
   75        */
   76       public static final String MAIN_CLASS = "org.apache.tools.ant.Main";
   77   
   78       /**
   79        * System property with user home directory.
   80        * {@value}
   81        */
   82       public static final String USER_HOMEDIR = "user.home";
   83   
   84       /**
   85        * System property with application classpath.
   86        * {@value}
   87        */
   88       private static final String JAVA_CLASS_PATH = "java.class.path";
   89   
   90       /**
   91        * Exit code on trouble
   92        */
   93       protected static final int EXIT_CODE_ERROR = 2;
   94   
   95       /**
   96        * Entry point for starting command line Ant.
   97        *
   98        * @param  args commandline arguments
   99        */
  100       public static void main(String[] args) {
  101           int exitCode;
  102           try {
  103               Launcher launcher = new Launcher();
  104               exitCode = launcher.run(args);
  105           } catch (LaunchException e) {
  106               exitCode = EXIT_CODE_ERROR;
  107               System.err.println(e.getMessage());
  108           } catch (Throwable t) {
  109               exitCode = EXIT_CODE_ERROR;
  110               t.printStackTrace(System.err);
  111           }
  112           if (exitCode != 0) {
  113               System.exit(exitCode);
  114           }
  115       }
  116   
  117   
  118       /**
  119        * Add a CLASSPATH or -lib to lib path urls.
  120        *
  121        * @param path        the classpath or lib path to add to the libPathULRLs
  122        * @param getJars     if true and a path is a directory, add the jars in
  123        *                    the directory to the path urls
  124        * @param libPathURLs the list of paths to add to
  125        */
  126       private void addPath(String path, boolean getJars, List libPathURLs)
  127               throws MalformedURLException {
  128           StringTokenizer tokenizer = new StringTokenizer(path, File.pathSeparator);
  129           while (tokenizer.hasMoreElements()) {
  130               String elementName = tokenizer.nextToken();
  131               File element = new File(elementName);
  132               if (elementName.indexOf("%") != -1 && !element.exists()) {
  133                   continue;
  134               }
  135               if (getJars && element.isDirectory()) {
  136                   // add any jars in the directory
  137                   URL[] dirURLs = Locator.getLocationURLs(element);
  138                   for (int j = 0; j < dirURLs.length; ++j) {
  139                       libPathURLs.add(dirURLs[j]);
  140                   }
  141               }
  142   
  143               libPathURLs.add(Locator.fileToURL(element));
  144           }
  145       }
  146   
  147       /**
  148        * Run the launcher to launch Ant.
  149        *
  150        * @param args the command line arguments
  151        * @return an exit code. As the normal ant main calls exit when it ends,
  152        *         this is for handling failures at bind-time
  153        * @exception MalformedURLException if the URLs required for the classloader
  154        *            cannot be created.
  155        */
  156       private int run(String[] args)
  157               throws LaunchException, MalformedURLException {
  158           String antHomeProperty = System.getProperty(ANTHOME_PROPERTY);
  159           File antHome = null;
  160   
  161           File sourceJar = Locator.getClassSource(getClass());
  162           File jarDir = sourceJar.getParentFile();
  163           String mainClassname = MAIN_CLASS;
  164   
  165           if (antHomeProperty != null) {
  166               antHome = new File(antHomeProperty);
  167           }
  168   
  169           if (antHome == null || !antHome.exists()) {
  170               antHome = jarDir.getParentFile();
  171               System.setProperty(ANTHOME_PROPERTY, antHome.getAbsolutePath());
  172           }
  173   
  174           if (!antHome.exists()) {
  175               throw new LaunchException("Ant home is set incorrectly or "
  176                   + "ant could not be located");
  177           }
  178   
  179           List libPaths = new ArrayList();
  180           String cpString = null;
  181           List argList = new ArrayList();
  182           String[] newArgs;
  183           boolean  noUserLib = false;
  184           boolean  noClassPath = false;
  185   
  186           for (int i = 0; i < args.length; ++i) {
  187               if (args[i].equals("-lib")) {
  188                   if (i == args.length - 1) {
  189                       throw new LaunchException("The -lib argument must "
  190                           + "be followed by a library location");
  191                   }
  192                   libPaths.add(args[++i]);
  193               } else if (args[i].equals("-cp")) {
  194                   if (i == args.length - 1) {
  195                       throw new LaunchException("The -cp argument must "
  196                           + "be followed by a classpath expression");
  197                   }
  198                   if (cpString != null) {
  199                       throw new LaunchException("The -cp argument must "
  200                           + "not be repeated");
  201                   }
  202                   cpString = args[++i];
  203               } else if (args[i].equals("--nouserlib") || args[i].equals("-nouserlib")) {
  204                   noUserLib = true;
  205               } else if (args[i].equals("--noclasspath") || args[i].equals("-noclasspath")) {
  206                   noClassPath = true;
  207               } else if (args[i].equals("-main")) {
  208                   if (i == args.length - 1) {
  209                       throw new LaunchException("The -main argument must "
  210                               + "be followed by a library location");
  211                   }
  212                   mainClassname = args[++i];
  213               } else {
  214                   argList.add(args[i]);
  215               }
  216           }
  217   
  218           //decide whether to copy the existing arg set, or
  219           //build a new one from the list of all args excluding the special
  220           //operations that only we handle
  221           if (argList.size() == args.length) {
  222               newArgs = args;
  223           } else {
  224               newArgs = (String[]) argList.toArray(new String[argList.size()]);
  225           }
  226   
  227           URL[] libURLs    = getLibPathURLs(
  228               noClassPath ? null : cpString, libPaths);
  229           URL[] systemURLs = getSystemURLs(jarDir);
  230           URL[] userURLs   = noUserLib ? new URL[0] : getUserURLs();
  231   
  232           URL[] jars = getJarArray(
  233               libURLs, userURLs, systemURLs, Locator.getToolsJar());
  234   
  235           // now update the class.path property
  236           StringBuffer baseClassPath
  237               = new StringBuffer(System.getProperty(JAVA_CLASS_PATH));
  238           if (baseClassPath.charAt(baseClassPath.length() - 1)
  239                   == File.pathSeparatorChar) {
  240               baseClassPath.setLength(baseClassPath.length() - 1);
  241           }
  242   
  243           for (int i = 0; i < jars.length; ++i) {
  244               baseClassPath.append(File.pathSeparatorChar);
  245               baseClassPath.append(Locator.fromURI(jars[i].toString()));
  246           }
  247   
  248           System.setProperty(JAVA_CLASS_PATH, baseClassPath.toString());
  249   
  250           URLClassLoader loader = new URLClassLoader(jars);
  251           Thread.currentThread().setContextClassLoader(loader);
  252           Class mainClass = null;
  253           int exitCode = 0;
  254           try {
  255               mainClass = loader.loadClass(mainClassname);
  256               AntMain main = (AntMain) mainClass.newInstance();
  257               main.startAnt(newArgs, null, null);
  258           } catch (InstantiationException ex) {
  259               System.err.println(
  260                   "Incompatible version of " + mainClassname + " detected");
  261               File mainJar = Locator.getClassSource(mainClass);
  262               System.err.println(
  263                   "Location of this class " + mainJar);
  264               exitCode = EXIT_CODE_ERROR;
  265           } catch (Throwable t) {
  266               t.printStackTrace(System.err);
  267               exitCode = EXIT_CODE_ERROR;
  268           }
  269           return exitCode;
  270       }
  271   
  272       /**
  273        * Get the list of -lib enties and -cp entry into
  274        * a URL array.
  275        * @param cpString the classpath string
  276        * @param libPaths the list of -lib entries.
  277        * @return an array of URLs.
  278        */
  279       private URL[] getLibPathURLs(String cpString, List libPaths)
  280           throws MalformedURLException {
  281           List libPathURLs = new ArrayList();
  282   
  283           if (cpString != null) {
  284               addPath(cpString, false, libPathURLs);
  285           }
  286   
  287           for (Iterator i = libPaths.iterator(); i.hasNext();) {
  288               String libPath = (String) i.next();
  289               addPath(libPath, true, libPathURLs);
  290           }
  291   
  292           return  (URL[]) libPathURLs.toArray(new URL[libPathURLs.size()]);
  293       }
  294   
  295       /**
  296        * Get the jar files in ANT_HOME/lib.
  297        * determine ant library directory for system jars: use property
  298        * or default using location of ant-launcher.jar
  299        */
  300       private URL[] getSystemURLs(File antLauncherDir) throws MalformedURLException {
  301           File antLibDir = null;
  302           String antLibDirProperty = System.getProperty(ANTLIBDIR_PROPERTY);
  303           if (antLibDirProperty != null) {
  304               antLibDir = new File(antLibDirProperty);
  305           }
  306           if ((antLibDir == null) || !antLibDir.exists()) {
  307               antLibDir = antLauncherDir;
  308               System.setProperty(ANTLIBDIR_PROPERTY, antLibDir.getAbsolutePath());
  309           }
  310           return Locator.getLocationURLs(antLibDir);
  311       }
  312   
  313       /**
  314        * Get the jar files in user.home/.ant/lib
  315        */
  316       private URL[] getUserURLs() throws MalformedURLException {
  317           File userLibDir
  318               = new File(System.getProperty(USER_HOMEDIR), USER_LIBDIR);
  319   
  320           return Locator.getLocationURLs(userLibDir);
  321       }
  322   
  323       /**
  324        * Combine the various jar sources into a single array of jars.
  325        * @param libJars the jars specified in -lib command line options
  326        * @param userJars the jars in ~/.ant/lib
  327        * @param systemJars the jars in $ANT_HOME/lib
  328        * @param toolsJar   the tools.jar file
  329        * @return a combined array
  330        * @throws MalformedURLException if there is a problem.
  331        */
  332       private URL[] getJarArray (
  333           URL[] libJars, URL[] userJars, URL[] systemJars, File toolsJar)
  334           throws MalformedURLException {
  335           int numJars = libJars.length + userJars.length + systemJars.length;
  336           if (toolsJar != null) {
  337               numJars++;
  338           }
  339           URL[] jars = new URL[numJars];
  340           System.arraycopy(libJars, 0, jars, 0, libJars.length);
  341           System.arraycopy(userJars, 0, jars, libJars.length, userJars.length);
  342           System.arraycopy(systemJars, 0, jars, userJars.length + libJars.length,
  343               systemJars.length);
  344   
  345           if (toolsJar != null) {
  346               jars[jars.length - 1] = Locator.fileToURL(toolsJar);
  347           }
  348           return jars;
  349       }
  350   }

Save This Page
Home » apache-ant-1.7.1-src » org.apache.tools » ant » launch » [javadoc | source]