ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Stefan Reich" <...@drjava.de>
Subject [PATCH] Lazy task class loading
Date Sat, 21 Jul 2001 17:25:43 GMT
Hi,

currently Ant loads all taskdef classes (as defined in defaults.properties) on startup. This
mechanism has at least 3 drawbacks:

-It can take up to one second or longer (if you use ant for everyday development, you will
notice the difference)
-It wastes memory
-It completely lacks descriptive error messages. For example, if you use <junit>, but
junit.jar isn't in your classpath, you only get a default message telling you something about
optional.jar. I've been puzzled as to why tasks couldn't be loaded more than once.

I would like to submit a patch that solves all three problems. I also took care to ensure
that the public interface of org.apache.tools.ant.Project is backward compatible.

-Stefan

Here is the patch against recent CVS (I already added @author tags for your convenience ;-):

Index: main/org/apache/tools/ant/Project.java
===================================================================
RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/Project.java,v
retrieving revision 1.64
diff -u -r1.64 Project.java
--- main/org/apache/tools/ant/Project.java 2001/07/17 12:12:39 1.64
+++ main/org/apache/tools/ant/Project.java 2001/07/21 17:03:14
@@ -68,6 +68,7 @@
  * file paths at runtime as well as defining various project properties.
  *
  * @author duncan@x180.com
+ * @author Stefan Reich <a href="mailto:doc@drjava.de">doc@drjava.de</a>
  */
 
 public class Project {
@@ -101,7 +102,8 @@
     private Hashtable references = new Hashtable();
     private String defaultTarget;
     private Hashtable dataClassDefinitions = new Hashtable();
-    private Hashtable taskClassDefinitions = new Hashtable();
+    private TaskDefinitionHashtable taskClassDefinitions = new TaskDefinitionHashtable();
+    
     private Hashtable targets = new Hashtable();
     private Hashtable filters = new Hashtable();
     private File baseDir;
@@ -114,6 +116,27 @@
     /** The system classloader - may be null */    
     private ClassLoader systemLoader = null;
     
+    public static class TaskDefinitionHashtable extends Hashtable {
+      /** lazily call Class.forName */
+      public Object get(Object key) {
+        Object value = super.get(key);
+        if (value instanceof String) {
+          try {
+            value = Class.forName((String) value);
+          } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e.toString());
+          } catch (NoClassDefFoundError e) {
+            throw new RuntimeException(e.toString());
+          }
+        }
+        return value;
+      }
+      
+      public String getClassName(Object key) {
+        return (String) super.get(key);
+      }
+    }
+    
     static {
 
         // Determine the Java version by looking at available classes
@@ -161,19 +184,23 @@
             props.load(in);
             in.close();
 
+            long startTime = System.currentTimeMillis();
             Enumeration enum = props.propertyNames();
             while (enum.hasMoreElements()) {
                 String key = (String) enum.nextElement();
                 String value = props.getProperty(key);
-                try {
+                /*try {
                     Class taskClass = Class.forName(value);
                     addTaskDefinition(key, taskClass);
                 } catch (NoClassDefFoundError ncdfe) {
                     // ignore...
                 } catch (ClassNotFoundException cnfe) {
                     // ignore...
-                }
+                }*/
+                addTaskDefinition(key, value);
             }
+            long endTime = System.currentTimeMillis();
+            System.out.println("Class loading took "+(endTime-startTime)+" ms");
         } catch (IOException ioe) {
             throw new BuildException("Can't load default task list");
         }
@@ -367,13 +394,19 @@
         log("Detected OS: " + System.getProperty("os.name"), MSG_VERBOSE);
     }
 
+    public void addTaskDefinition(String taskName, String taskClass) {
+        String msg = " +User task: " + taskName + "     " + taskClass;
+        log(msg, MSG_DEBUG);
+        taskClassDefinitions.put(taskName, taskClass);
+    }
+
     public void addTaskDefinition(String taskName, Class taskClass) {
         String msg = " +User task: " + taskName + "     " + taskClass.getName();
         log(msg, MSG_DEBUG);
         taskClassDefinitions.put(taskName, taskClass);
     }
 
-    public Hashtable getTaskDefinitions() {
+    public TaskDefinitionHashtable getTaskDefinitions() {
         return taskClassDefinitions;
     }
 
@@ -445,7 +478,12 @@
     }
 
     public Task createTask(String taskType) throws BuildException {
-        Class c = (Class) taskClassDefinitions.get(taskType);
+        Class c;
+        try {
+          c = (Class) taskClassDefinitions.get(taskType);
+        } catch (RuntimeException e) {
+          throw new BuildException(e.getMessage());
+        }
 
         if (c == null)
             return null;
Index: main/org/apache/tools/ant/taskdefs/Ant.java
===================================================================
RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Ant.java,v
retrieving revision 1.23
diff -u -r1.23 Ant.java
--- main/org/apache/tools/ant/taskdefs/Ant.java 2001/07/06 11:57:29 1.23
+++ main/org/apache/tools/ant/taskdefs/Ant.java 2001/07/21 17:03:15
@@ -76,6 +76,7 @@
  *
  *
  * @author costin@dnt.ro
+ * @author Stefan Reich <a href="mailto:doc@drjava.de">doc@drjava.de</a>
  */
 public class Ant extends Task {
 
@@ -143,11 +144,11 @@
             }
         }
 
-        Hashtable taskdefs = project.getTaskDefinitions();
+        Project.TaskDefinitionHashtable taskdefs = project.getTaskDefinitions();
         Enumeration et = taskdefs.keys();
         while (et.hasMoreElements()) {
             String taskName = (String) et.nextElement();
-            Class taskClass = (Class) taskdefs.get(taskName);
+            String taskClass = taskdefs.getClassName(taskName);
             p1.addTaskDefinition(taskName, taskClass);
         }



Mime
View raw message