ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul Kilroy <pkil...@channelpoint.com>
Subject RE: [PATCH] Lazy task class loading
Date Tue, 07 Aug 2001 16:20:30 GMT
I'd like to give my +1 for this even though I'm not a commiter, because:
 
-If you have the source for a new task in the same tree that uses it, you
are unable to build w/o first commenting out the taskdef to build the task,
then uncommenting it to build the rest of your tree. (Unless there's a way I
couldn't find ;)
 
Paul

-----Original Message-----
From: Stefan Reich [mailto:doc@drjava.de]
Sent: Tuesday, August 07, 2001 8:34 AM
To: ant-dev@jakarta.apache.org
Subject: Re: [PATCH] Lazy task class loading


Hi Ant developers-in-charge,
 
I sent this to the list two weeks ago and didn't get any reply.
 
Can you please give me an indication whether this patch is at all useful? Or
if you think it isn't, then tell me why. I would really like to know that.
 
I have a couple of ideas for other patches to submit; but I don't want to go
through the hassle to prepare them if there is no interest. So I'm using
this patch as a kind of test balloon ;-)
 
Best,
-Stefan

----- Original Message ----- 
From: Stefan Reich <mailto:doc@drjava.de>  
To: ant-dev@jakarta.apache.org <mailto:ant-dev@jakarta.apache.org>  
Sent: Saturday, July 21, 2001 7:25 PM
Subject: [PATCH] Lazy task class loading

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 <mailto:duncan@x180.com> 
+ * @author Stefan Reich <a href="mailto:doc@drjava.de" <mailto:href=> >
doc@drjava.de <mailto: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 <file://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 <file://long>  endTime = System.currentTimeMillis();
+            System.out.println <file://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 <mailto:costin@dnt.ro> 
+ * @author Stefan Reich <a href="mailto:doc@drjava.de" <mailto:href=> >
doc@drjava.de <mailto: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