Not sure if this exists somewhere other then Antidote, but I sometimes
(actually all the time) have the need to repeat small builds frequently
from the command line. Invoking a JVM every time is really slow and
makes Ant a bit painful at times.

So, I came up with a new class (Cmd.java, goes into
src/main/org/apache/tools/ant directory) which works together with
Main.java (its runBuild() was changed from private to protected). It
basically waits for the input from the command line and then runs the
targets based on what you typed in. If nothing was typed (ie. you just
press <ENTER>) it executes the default target. Once you type '\q', it
exits (this might be a problem for people that have targets named '\q',
not many I would like to believe).

In practice, this brings repeated build times from say 11 - 12 seconds
to 0 - 4 seconds (AMD K6-2 350MHz, RedHat Linux 7, Sun's JDK 1.3.0_02),
especially after you've done it a few times, plus there is no delay in
starting the JVM, which is another few seconds.

The attached files:

- Cmd.java:
  - the actual work class, replaces main() from Main.java
- Main.java.patch:
  - the runBuild() method has to be protected, not private
    in order for Cmd.java to work (not sure if I broke
    anything with this)
- antcmd and antcmd.bat:
  - scripts to start this new class (a changed copy of
    ant and ant.bat)
- build.xml.patch:
  - build file patch in order to make antcmd executable on Unix

Bojan

PS. Have a feeling that 1.4alpha works faster then 1.3 for XSLT. Kudos
to all people that contributed to that...
--- jakarta-ant-cvs/src/main/org/apache/tools/ant/Main.java     Sun Apr 29 
20:36:31 2001
+++ jakarta-ant/src/main/org/apache/tools/ant/Main.java Sun Apr 29 20:54:40 2001
@@ -364,7 +364,7 @@
     /**
      * Executes the build.
      */
-    private void runBuild() throws BuildException {
+    protected void runBuild() throws BuildException {
 
         if (!readyToRun) {
             return;
#! /bin/sh

if [ -f $HOME/.antrc ] ; then 
  . $HOME/.antrc
fi

# Cygwin support.  $cygwin _must_ be set to either true or false.
case "`uname`" in
  CYGWIN*) cygwin=true ;;
  *) cygwin=false ;;
esac

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin; then
  [ -n "$ANT_HOME" ] &&
    ANT_HOME=`cygpath --unix "$ANT_HOME"`
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
  [ -n "$CLASSPATH" ] &&
    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi

if [ "$ANT_HOME" = "" ] ; then
  # try to find ANT
  if [ -d /opt/ant ] ; then 
    ANT_HOME=/opt/ant
  fi

  if [ -d ${HOME}/opt/ant ] ; then 
    ANT_HOME=${HOME}/opt/ant
  fi

  ## resolve links - $0 may be a link to ant's home
  PRG=$0
  progname=`basename $0`
  
  while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '.*/.*' > /dev/null; then
        PRG="$link"
    else
        PRG="`dirname $PRG`/$link"
    fi
  done
  
  ANT_HOME=`dirname "$PRG"`/..

fi

if [ "$JAVA_HOME" != "" ] ; then
  if [ "$JAVACMD" = "" ] ; then 
    JAVACMD=$JAVA_HOME/bin/java
  fi
else
  if [ "$JAVACMD" = "" ] ; then 
    JAVACMD=java
  fi
fi
 
# add in the dependency .jar files
DIRLIBS=${ANT_HOME}/lib/*.jar
for i in ${DIRLIBS}
do
    # if the directory is empty, then it will return the input string
    # this is stupid, so case for it
    if [ "$i" != "${DIRLIBS}" ] ; then
        LOCALCLASSPATH=$LOCALCLASSPATH:"$i"
    fi
done

if [ "$CLASSPATH" != "" ] ; then
  LOCALCLASSPATH=$CLASSPATH:$LOCALCLASSPATH
fi

if [ "$JAVA_HOME" != "" ] ; then
  if test -f $JAVA_HOME/lib/tools.jar ; then
    LOCALCLASSPATH=$LOCALCLASSPATH:$JAVA_HOME/lib/tools.jar
  fi

  if test -f $JAVA_HOME/lib/classes.zip ; then
    LOCALCLASSPATH=$LOCALCLASSPATH:$JAVA_HOME/lib/classes.zip
  fi
else
  echo "Warning: JAVA_HOME environment variable is not set."
  echo "  If build fails because sun.* classes could not be found"
  echo "  you will need to set the JAVA_HOME environment variable"
  echo "  to the installation directory of java."
fi

# supply JIKESPATH to Ant as jikes.class.path
if [ "$JIKESPATH" != "" ] ; then
  if [ "$ANT_OPTS" != "" ] ; then
    ANT_OPTS="$ANT_OPTS -Djikes.class.path=$JIKESPATH"
  else
    ANT_OPTS=-Djikes.class.path=$JIKESPATH
  fi
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
  ANT_HOME=`cygpath --path --windows "$ANT_HOME"`
  JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
  LOCALCLASSPATH=`cygpath --path --windows "$LOCALCLASSPATH"`
fi

$JAVACMD -classpath "$LOCALCLASSPATH" -Dant.home="${ANT_HOME}" $ANT_OPTS 
org.apache.tools.ant.Cmd "$@"
@echo off

if exist "%HOME%\antrc_pre.bat" call "%HOME%\antrc_pre.bat"

if not "%OS%"=="Windows_NT" goto win9xStart
:winNTStart
@setlocal

rem %~dp0 is name of current script under NT
set DEFAULT_ANT_HOME=%~dp0

rem : operator works similar to make : operator
set DEFAULT_ANT_HOME=%DEFAULT_ANT_HOME:\bin\=%

if %ANT_HOME%a==a set ANT_HOME=%DEFAULT_ANT_HOME%
set DEFAULT_ANT_HOME=

rem On NT/2K grab all arguments at once
set ANT_CMD_LINE_ARGS=%*
goto doneStart

:win9xStart
rem Slurp the command line arguments.  This loop allows for an unlimited number 
of 
rem agruments (up to the command line limit, anyway).

set ANT_CMD_LINE_ARGS=

:setupArgs
if %1a==a goto doneStart
set ANT_CMD_LINE_ARGS=%ANT_CMD_LINE_ARGS% %1
shift
goto setupArgs

:doneStart
rem This label provides a place for the argument list loop to break out 
rem and for NT handling to skip to.

rem find ANT_HOME
if not "%ANT_HOME%"=="" goto checkJava

rem check for ant in Program Files on system drive
if not exist "%SystemDrive%\Program Files\ant" goto checkSystemDrive
set ANT_HOME=%SystemDrive%\Program Files\ant
goto checkJava

:checkSystemDrive
rem check for ant in root directory of system drive
if not exist "%SystemDrive%\ant" goto noAntHome
set ANT_HOME=%SystemDrive%\ant
goto checkJava

:noAntHome
echo ANT_HOME is not set and ant could not be located. Please set ANT_HOME.
goto end

:checkJava
set _JAVACMD=%JAVACMD%
set LOCALCLASSPATH="%CLASSPATH%"
for %%i in ("%ANT_HOME%\lib\*.jar") do call "%ANT_HOME%\bin\lcp.bat" "%%i"

if "%JAVA_HOME%" == "" goto noJavaHome
if "%_JAVACMD%" == "" set _JAVACMD=%JAVA_HOME%\bin\java
if exist "%JAVA_HOME%\lib\tools.jar" call "%ANT_HOME%\bin\lcp.bat" 
"%JAVA_HOME%\lib\tools.jar"
if exist "%JAVA_HOME%\lib\classes.zip" call "%ANT_HOME%\bin\lcp.bat" 
"%JAVA_HOME%\lib\classes.zip"
goto checkJikes

:noJavaHome
if "%_JAVACMD%" == "" set _JAVACMD=java
echo.
echo Warning: JAVA_HOME environment variable is not set.
echo   If build fails because sun.* classes could not be found
echo   you will need to set the JAVA_HOME environment variable
echo   to the installation directory of java.
echo.

:checkJikes
if not "%JIKESPATH%" == "" goto runAntWithJikes

:runAnt
%_JAVACMD% -classpath %LOCALCLASSPATH% -Dant.home="%ANT_HOME%" %ANT_OPTS% 
org.apache.tools.ant.Cmd %ANT_CMD_LINE_ARGS%
goto end

:runAntWithJikes
%_JAVACMD% -classpath %LOCALCLASSPATH% -Dant.home="%ANT_HOME%" 
-Djikes.class.path=%JIKESPATH% %ANT_OPTS% org.apache.tools.ant.Cmd 
%ANT_CMD_LINE_ARGS%

:end
set LOCALCLASSPATH=
set _JAVACMD=
set ANT_CMD_LINE_ARGS=

if not "%OS%"=="Windows_NT" goto mainEnd
:winNTend
@endlocal

:mainEnd
if exist "%HOME%\antrc_post.bat" call "%HOME%\antrc_post.bat"

--- jakarta-ant-cvs/build.xml   Sun Apr 29 20:36:34 2001
+++ jakarta-ant/build.xml       Sun Apr 29 21:06:05 2001
@@ -289,6 +289,7 @@
     <chmod perm="ugo+x" type="file">
        <fileset dir="${dist.bin}">
          <include name="**/ant" />
+         <include name="**/antcmd" />
          <include name="**/antRun" />
          <include name="**/runant.pl" />
        </fileset>
/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999, 2000 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 [EMAIL PROTECTED]
 *
 * 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
 * <http://www.apache.org/>.
 */

package org.apache.tools.ant;

import java.io.*;
import java.util.*;

/**
 * Command line utility for Ant. Removes the need to start JVM
 * every time your run a new build in the same directory.
 *
 * @author Bojan Smojver <[EMAIL PROTECTED]>
 */

public class Cmd extends org.apache.tools.ant.Main{
  static final String prompt="ant> ";
  static final String exit="\\q";

  protected Cmd(String[] args) throws BuildException{
    super(args);
  }

  public static void main(String args[]){
     LineNumberReader inp=new LineNumberReader(
                          new InputStreamReader(System.in));
     String cmd="";
     Cmd ac=null;

     try{
       System.out.print(prompt);

       while(!(cmd=inp.readLine()).trim().equals(exit)){
         StringTokenizer st=new StringTokenizer(cmd);
         String[] arg=new String[st.countTokens()];

         for(int i=0;i<arg.length;i++){
           arg[i]=st.nextToken();
         }

         try{
           ac=new Cmd(arg);
           ac.runBuild();
         } catch(BuildException e){
           System.err.println("OOPS! BuildException occured.");
         }
         System.out.print(prompt);
       }
     } catch(IOException e){
       System.err.println("OOPS! IOException occured. Have to quit.");
     }
  }
}

Reply via email to