ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Guy Gur-Ari <guy...@yahoo.com>
Subject [PATCH] Loop-mode feature (a.k.a. 'incremental')
Date Wed, 24 Jul 2002 01:09:00 GMT
Hi all,
I wrote a small patch that adds support for 'loop' mode (or
'incremental' mode) when running ant.

The feature kicks in when running 'ant -loop': Instead of exiting when a
build completes, ant continues to run with a 'Press Enter to build
again...' message. When Enter is pressed ant simply loops and reruns the
build. The build file and other properties are reread on each iteration.

The motivation is to solve a performance problem on some machines during
ant startup, that happens because of slow JVM startup and class loading.
The patch changes things so that the JVM and classes are loaded only
once. 

I tried it on a Solaris machine with NFS access to the ant JAR. Using
loop mode, a do-nothing 'prepare, remove-depends, compile' run took 10
seconds for the first iteration, and 2.5 seconds for subsequent
iterations. On a Linux box with local disks the improvement was
negligible -- an improvement of ~0.5 secs.

Here's it is (this is my first time submitting patches to this list;
please correct me if I'm doing anything wrong):

--- PATCH BEGINS ---
Index: src/main/org/apache/tools/ant/Main.java
===================================================================
RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/Main.java,v
retrieving revision 1.72
diff -u -r1.72 Main.java
--- src/main/org/apache/tools/ant/Main.java	23 Jul 2002 15:13:37 -0000	1.72
+++ src/main/org/apache/tools/ant/Main.java	24 Jul 2002 21:46:45 -0000
@@ -64,6 +64,8 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
 import java.util.Vector;
 import java.util.Properties;
 import java.util.Enumeration;
@@ -139,6 +141,9 @@
      */
     private boolean projectHelp = false;
 
+    /** Whether to build repeatedly */
+    private boolean loopMode = false;
+
     /**
      * Whether or not a logfile is being used. This is used to
      * check if the output streams must be closed.
@@ -162,7 +167,9 @@
     /**
      * Creates a new instance of this class using the
      * arguments specified, gives it any extra user properties which have been
-     * specified, and then runs the build using the classloader provided.
+     * specified, and then runs the build using the classloader provided.<p>
+     *
+     * When in loop mode, this method never returns unless there's an error.
      *
      * @param args Command line arguments. Must not be <code>null</code>.
      * @param additionalUserProperties Any extra properties to use in this
@@ -174,54 +181,77 @@
     public static void start(String[] args, Properties additionalUserProperties,
                              ClassLoader coreLoader) {
         Main m = null;
+        int exitCode;
 
-        try {
-            Diagnostics.validateVersion();
-            m = new Main(args);
-        } catch (Throwable exc) {
-            printMessage(exc);
-            System.exit(1);
-        }
+        // Loop-mode loop
+        do {
+            // expect the worst
+            exitCode = 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 {
+                Diagnostics.validateVersion();
+                m = new Main(args);
+            } catch (Throwable exc) {
+                printMessage(exc);
+                break;
             }
-        }
 
-        // expect the worst
-        int exitCode = 1;
-        try {
-            m.runBuild(coreLoader);
-            exitCode = 0;
-        } catch (BuildException be) {
-            if (m.err != System.err) {
-                printMessage(be);
-            }
-        } catch (Throwable exc) {
-            exc.printStackTrace();
-            printMessage(exc);
-        } finally {
-            if (isLogFileUsed) {
-                if (out != null) {
-                    try {
-                        out.close();
-                    } catch (final Exception e) {
-                        //ignore
-                    }
+            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);
                 }
-                if (err != null) {
-                    try {
-                        err.close();
-                    } catch (final Exception e) {
-                        //ignore
+            }
+
+            try {
+                m.runBuild(coreLoader);
+                exitCode = 0;
+            } catch (BuildException be) {
+                if (m.err != System.err) {
+                    printMessage(be);
+                }
+                // Continue to next iteration if a build error occurs while in
+                // loop mode
+            } catch (Throwable exc) {
+                exc.printStackTrace();
+                printMessage(exc);
+                break;
+            } finally {
+                if (isLogFileUsed) {
+                    if (out != null) {
+                        try {
+                            out.close();
+                        } catch (final Exception e) {
+                            //ignore
+                        }
+                    }
+                    if (err != null) {
+                        try {
+                            err.close();
+                        } catch (final Exception e) {
+                            //ignore
+                        }
                     }
                 }
             }
-        }
+
+            if (m.loopMode) {
+                try {
+                    waitForUserKey();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    printMessage(e);
+                    exitCode = 1;
+
+                    // We couldn't get a user key, so if we continue we run the
+                    // risk of going into a tight loop
+                    break;
+                }
+            }
+        } while (m.loopMode);
+
         System.exit(exitCode);
     }
 
@@ -387,6 +417,8 @@
                     System.out.println(msg);
                     return;
                 }
+            } else if (arg.equals("-loop")) {
+                loopMode = true;
             } else if (arg.startsWith("-")) {
                 // we don't have any more args to recognize!
                 String msg = "Unknown argument: " + arg;
@@ -759,6 +791,8 @@
         msg.append("  -inputhandler <class>  the class which will handle input requests"
+ lSep);
         msg.append("  -find <file>           search for buildfile towards the root
of the" + lSep);
         msg.append("                         filesystem and use it" + lSep);
+        msg.append("  -loop                  build repeatedly without exiting," + lSep);
+        msg.append("                         waiting for user input between iterations" +
lSep);
         System.out.println(msg.toString());
     }
 
@@ -945,5 +979,16 @@
             msg.append(lSep);
         }
         project.log(msg.toString());
+    }
+
+    /**
+     * Displays a short message and waits for the user to press Enter.
+     */
+    private static void waitForUserKey() throws IOException {
+        System.out.println("\nPress Enter to build again...");
+
+        BufferedReader reader = new BufferedReader(
+                new InputStreamReader(System.in));
+        reader.readLine();
     }
 }
--- PATCH ENDS ---

Guy


--
To unsubscribe, e-mail:   <mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>


Mime
View raw message