Hi Conor, oh, seems like I overloked Stefan's comment in the thunderstorm of 500 holiday emails.
I'll wait until your thunderstorm settles then. Keep going with that Ant release! Thanks for your reply, -Stefan ----- Original Message ----- From: "Conor MacNeill" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Tuesday, August 07, 2001 5:17 PM Subject: Re: [PATCH] Lazy task class loading > Stefan, > > You've sent up your test balloon in the middle of the thunderstorm that is > an Ant release. We have done just a cursory look at the outstanding > patches. It is still a long queue. Stefan Bodewig gave this feedback. > > * lazy classloading > > I'm fine with the changes to project, but not with the changes to > <ant>, as they will lose class loader information for custom taskdefs > > Cheers > Conor > > ----- Original Message ----- > From: "Stefan Reich" <[EMAIL PROTECTED]> > To: <[EMAIL PROTECTED]> > Sent: Wednesday, August 08, 2001 12:33 AM > 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 > To: [EMAIL PROTECTED] > 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 [EMAIL PROTECTED] > + * @author Stefan Reich <a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</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 [EMAIL PROTECTED] > + * @author Stefan Reich <a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</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); > } > > > >
