You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Peter Donald <do...@mad.scientist.com> on 2000/06/14 11:58:24 UTC

[RFE] Richer Task Specification

Hi,

I am not sure of the usuall process for a Request For Enhancement (RFE) but
I guess I'll just say what I want :P. I want to see the ability to specify
tasks more richly. 

Request 1:
----------

Currently there is a whole bunch of classes that gain reusability through
inheritance. This IMHO is a bad idea. While you could factor out the
relevant code into helper classes it still doesn't seem good design. For
instance many people have been wanting various tasks to match files in
various ways etc and duplicating code or else calling out to other static
methods.

What I would like is some method of knowing how to preprocess properties so
that they are in form task wants. So instead of tasks such as javac calling
resolvepath/translatepath/whatever it would already be passed to the task
pre-processed. This would also mean it would be possible to have properties
that are not strings and in fact could effectively be any Object.

So to get this working there needs to be two problems solved, namely
conversion and processing. It may be the case that these two processes can
be combined into one step (thou I am not sure if this is the right way(tm) ).

To write a converter you simply have to implement the interface

interface Converter
{
  Object convert( Object object );
}

and then register it at some registry via

myRegistry.registerConverter( new StringToFileConverter(), 
                              String.class,
                              File.class );

and then convert it just before passing to task via

myRegistry.getConverter( String.class, File.class ).convert( param );

So thus you could have a task with a property of type File. It would
automatically be converteed from a string to a File object. 

I did almost an identical thing recently but unfortunately I don't own the
code. I believe similar things occur in a number of projects such as BML at
www.alphaworks.ibm.com and jedit at sourceforge.net. The only problem I had
was that I ended up with an excessive number of Converter classes. This
could be aleviated if one converter accepted multiple input types and
registered itself as a converter for multiple types.

The processing could occur in a similar way with a registry and processors
etc. This would allow you to specify the attribute "src" as having a type
of "ant:filelist" or "ant:file" and automatically
translate/resolve/whatever to it. 

The problem is how do we know what processing any particular property
wants. We could do it by type (ie all File[] get processed vi translation
and reolving) however that is inflexible and can lead to problems when
different tasks want the property output in same manner but processed
differently.

Hence there are a number of approaches that I can see. Use JavaBeans
properties. The bean spec allows the author to add arbitary attributes to
fetures (ie properties) which could be used to specify the type. This may
be a possibility but it requires the task author also write an extra
BeanInfo class to specify extra attribute for property if they want any
sort of special processing. It also ties the project to java which others
may not want (python-ant anyone ? :P).

Alternatively a parser with schema support could be used and a
schema-fragment for each task be created. The schema fragment is then
merged with other fragments to form a fully happening schema. Tasks that
dont have any pre-processing requirements don't define a schema-fragment
and have theirs automatically generated from task class. So for task
com.biz.myTask you would look for resource /com/biz/myTask.schema and if it
not existing then  automatical generate it. 

Problems with the schema approach are the task developer has to be
partially aware of what a schema is and it also makes it impossible to
dynaically add taskdefs (which is something I ask for below :P). 

To decrease task developers cognitive load we could even auto-generate the
BeanInfo/schema based on javadocs comments. ie if we see a @task-type then
we know what comes next is the typename. This requires two passes (ie one
to write code and one specialised javadoc pass) but this could be hidden
from developer if we wanted.

I could go on and on about hows/whys to implement but I guess you get
picture here :P so I will stop.

Request 2:
----------

Would it be possible to have a bunch of standard ant properties in Tasks
that effect project in other manners.

For instance it would be nice to have 

<javac ant:classpath="blah.jar" .... />

This would mean that this task is automatically loaded by a new classloader
that included "blah.jar" and whatever else was specified. There are other
things that I would like to have thou are not sure of their merits. Some of
the things that people have mentioned recently include assynchronicity and
working directory thou there could be other factors that i haven't thought
of yet ...

Request 3:
----------

Could taskdefs be specified immediately. ie. move the main chunk of it from
init to execute. This would allow a single build file to compile the
taskdefs it needs and then use those in turn to do further processing. I
have to run build twice to get this solved and it bugs the hell out of me :P.

Request 4:
----------

A standardised set of taskdefs for invoking standard C/C++ tools (ie tasks
like make, cpp, cc, link etc). I keep writing hacky ones for whatever
particular compiler I am using at the time that are basically execs. Most
of my compilations have relatively standard parameters so maybe it would be
an idea to amalgamate them all into one task that then delegates to
appropriate lower-level driver ????


----------------------

I got a whole bunch of other requests but gotta eat now and besides they
are even more ludicrous than the ones I said above. So thoughts on it ?
Good/bad idea ? Improvements ? volunteers ? If people think it is a good
idea and no one volunteers I can can do it but it wont be a while
unfortunately :<


Cheers,

Pete

*------------------------------------------------------*
| "Nearly all men can stand adversity, but if you want |
| to test a man's character, give him power."          |
|       -Abraham Lincoln                               |
*------------------------------------------------------*

Re: [RFE] Richer Task Specification

Posted by James Duncan Davidson <ja...@eng.sun.com>.
on 6/14/00 8:40 AM, Stefan Bodewig at bodewig@bost.de wrote:

> PD> BTW spec/core.html is dated "Version 0.5 (2000/04/20)" and
> PD> doesn't seem to contain all I thought it would .. is there a new
> PD> version or should it be considered a work in progress ??
> 
> You should consider anything as a work in progress 8^).

Seconded! :)

> Unfortunately Ant has slipped a little bit down on the priority list
> of many of those people that used to be active contributers - no
> offense implied! 

None taken. :) After all, my time has been going into helping other very
good things happen -- which affects Ant.

It is time to take a look at the document again with the discussion that has
been going on.

.duncan


Re: [RFE] Richer Task Specification

Posted by Peter Donald <do...@mad.scientist.com>.
At 05:40  14/6/00 +0200, you wrote:
>In the case of one attribute being a directory that should be expanded
>to a file list it seems more likely that the list will be constraint
>by other attributes (judging from my own buildfiles where about two
>third of all MatchingTask implementations I call use include/exclude
>attributes).

hmm so really what is happening is 1 + N attributes are determining the
value of another hidden attribute (namely the filelist). Damn ... I can't
think of a good way to make that any easier without significant complexity
which is a bad thing :<

Can anyone else think of an easy (as in easy for task developers not
necessarily core developers) way besides inheritance/ugly delegation that
this can be done ?

>As to your wish to only display the output on some conditions - apart
>from the loglevel - I'm not sure. It doesn't feel right to me to
>bother the build tool with this - I would probably prefer a custom
>logfile postprocessor task .

possibly ... however it is not uncommon among other build tools (Well at
least those on Win32 ... *nix rarely puts superfolous messages out :P). I
guess I am too used to the unic way ... ie no news is good news or only
tell me something when something goes wrong (or I put on verbosity).

> PD> BTW spec/core.html is dated "Version 0.5 (2000/04/20)" and
> PD> doesn't seem to contain all I thought it would .. is there a new
> PD> version or should it be considered a work in progress ??
>
>You should consider anything as a work in progress 8^). 

ahh :P


Cheers,

Pete

*------------------------------------------------------*
| "Nearly all men can stand adversity, but if you want |
| to test a man's character, give him power."          |
|       -Abraham Lincoln                               |
*------------------------------------------------------*

Re: [RFE] Richer Task Specification

Posted by Stefan Bodewig <bo...@bost.de>.
>>>>> "PD" == Peter Donald <do...@mad.scientist.com> writes:

 PD> Is it often that the value of one attribute will effect the value
 PD> of another ? ie Does this happen often enough for it to be an
 PD> issue ?

In the case of one attribute being a directory that should be expanded
to a file list it seems more likely that the list will be constraint
by other attributes (judging from my own buildfiles where about two
third of all MatchingTask implementations I call use include/exclude
attributes).

 PD> okays thou I would hate to do logging on a task level. How do you
 PD> overide it ?

You can't by now. The way it has been proposed (not formally BTW) went
something like this:

add a final setLoglevel method to task - so each task has an attribute
named loglevel, remove the log method from Project and move it to
Task, let all Tasks use log() whenever they want to emit something, if
no explicit loglevel has been specified for a task, use the projects
default.

Add to this a setOutput method and let task log either to an
explicitly specified output file or to the project default - that can
be set via the -logfile switch.

Now you could specify the detail of logging and decide where the logs
go on a task by task basis - or don't specify anything with regard to
logging in the build file and things work like they always did.

As to your wish to only display the output on some conditions - apart
from the loglevel - I'm not sure. It doesn't feel right to me to
bother the build tool with this - I would probably prefer a custom
logfile postprocessor task .

 PD> BTW spec/core.html is dated "Version 0.5 (2000/04/20)" and
 PD> doesn't seem to contain all I thought it would .. is there a new
 PD> version or should it be considered a work in progress ??

You should consider anything as a work in progress 8^). 

Unfortunately Ant has slipped a little bit down on the priority list
of many of those people that used to be active contributers - no
offense implied! 

The document you mention was the result of two weeks of very active
discussion, after that some things have been clarified but no-one took
the time to update the document, sorry. The best thing you could do is
to get the mailing list index and read up on the threads with subjects
that start with "Ant principles".

Stefan

who still doesn't speak for the Ant development and hopes that others
have an opinion to your ideas as well.

Re: [RFE] Richer Task Specification

Posted by Peter Donald <do...@mad.scientist.com>.
At 02:04  14/6/00 +0200, you wrote:
> [About processing of attributes and where to put this]
>
> PD> I just hate seeing the same two lines or copied methods all
> PD> through my code
>
>We are in the same camp here. I just believe that the common
>processing of attributes - like generating file lists from directories
>- could be reused by factoring it out into a helper class - like
>DirectoryScanner - and delegate to it.
>
>We more or less agree on this just disagree where to put the
>delegation. I'd prefer to do so explicitly in the task while you
>prefer to intercept the attribute setting mechanism. Am I right?

essentially thats right ... make the core difficult and tasks simple.

>One thing that just comes to my mind is what to do if the meaning of
>one attribute changes the outcome of the processing step for another
>attribute? I think this can only be done if the processing happens in
>the task's init or execute method. I mean something like
>
><javac srcdir="..." excludes="testcases/**" />

>if you process srcdir to a file list how would you ensure the Java
>files from testcases are omitted?

good point ... how often does this occur ? Is it often that the value of
one attribute will effect the value of another ? ie Does this happen often
enough for it to be an issue ? Or could it be handled as a special case and
in those cases that require it make the effort ...

hmmm ... I think I may be coming around to your way of thinking ... sorta 


> PD> unfortunately classpath usually has to happen *before* task is
> PD> loaded .. 
>
>Yes, you are right. I guess the right solution is to use a custom
>classloader in the Java task (and maybe in Javac) whenever (1) the
>classpath is explicitly specified and (2) fork is false.

yep thats what I do now ... unfortunately I have to do for 4 seperate tasks
and it is fairly difficult to factor out .... so I was hoping to put it in
core ... but I guess I have a different approach. You want the core simple
and tasks difficult and the core simple while I swing the other way :P ...
I guess I can live with that ...

> PD> is that input and output get wrapped before each task executes.
>
>There has been a request to specify the level of logging on a task by
>task basis. Equally one could specify the logging output at the task
>level - using the projects default output when omitted. These could be
>done inside the Task base class. We have yet to see comments from the
>commiters on these issues (I'm not a commiter and far from speaking
>for Ant development).

okays thou I would hate to do logging on a task level. How do you overide
it ? 

If a task explicitly logs using project object then it is easy to redirect
it through the standard verbose/quite flags but what about stdout/stderr on
tasks executed. I would like to see something like only displaying it when
the task fails or verbose flag is ticked .... is that what you mean ????

BTW spec/core.html is dated "Version 0.5 (2000/04/20)" and doesn't seem to
contain all I thought it would .. is there a new version or should it be
considered a work in progress ??
Cheers,

Pete

*------------------------------------------------------*
| "Nearly all men can stand adversity, but if you want |
| to test a man's character, give him power."          |
|       -Abraham Lincoln                               |
*------------------------------------------------------*

Re: [RFE] Richer Task Specification

Posted by Stefan Bodewig <bo...@bost.de>.
>>>>> "PD" == Peter Donald <do...@mad.scientist.com> writes:

 PD> At 12:55 14/6/00 +0200, you wrote:

 >> The way to go for attributes (IIRC) was to use classes with a
 >> constructor taking a String object as its only argument.

 PD> okay ... sounds good for user created types but how about
 PD> standard types in java library .. 

File and URL have String constructors as well as say Integer. For File
you might want to use resolveFile before calling the constructor or
use a subclass of File that resolves the File itself.

Special cases for the primitive types have been considered - although
I can't remember whether they were accepted or dropped in favor of the
wrapper classes from java.lang.

 [About processing of attributes and where to put this]

 PD> I just hate seeing the same two lines or copied methods all
 PD> through my code

We are in the same camp here. I just believe that the common
processing of attributes - like generating file lists from directories
- could be reused by factoring it out into a helper class - like
DirectoryScanner - and delegate to it.

We more or less agree on this just disagree where to put the
delegation. I'd prefer to do so explicitly in the task while you
prefer to intercept the attribute setting mechanism. Am I right?

One thing that just comes to my mind is what to do if the meaning of
one attribute changes the outcome of the processing step for another
attribute? I think this can only be done if the processing happens in
the task's init or execute method. I mean something like

<javac srcdir="..." excludes="testcases/**" />

if you process srcdir to a file list how would you ensure the Java
files from testcases are omitted?

 PD> unfortunately classpath usually has to happen *before* task is
 PD> loaded .. 

Yes, you are right. I guess the right solution is to use a custom
classloader in the Java task (and maybe in Javac) whenever (1) the
classpath is explicitly specified and (2) fork is false.

 PD> is that input and output get wrapped before each task executes.

There has been a request to specify the level of logging on a task by
task basis. Equally one could specify the logging output at the task
level - using the projects default output when omitted. These could be
done inside the Task base class. We have yet to see comments from the
commiters on these issues (I'm not a commiter and far from speaking
for Ant development).

Stefan

Re: [RFE] Richer Task Specification

Posted by Peter Donald <do...@mad.scientist.com>.
At 12:55  14/6/00 +0200, you wrote:
>>>>>> "PD" == Peter Donald <do...@mad.scientist.com> writes:
>
> PD> What I would like is some method of knowing how to preprocess
> PD> properties so that they are in form task wants.  [...]  This
> PD> would also mean it would be possible to have properties that are
> PD> not strings and in fact could effectively be any Object.
>
>Peter, take a look at spec/core.html. Some things you want are already
>there, some things have been discussed and even been agreed on but
>unfortunately the document hasn't been updated to reflect this.

oh .. working of oldish (about a month) cvs copy thou I will have a look :P

>Basically it has been agreed that project properties as well as task
>attributes should be richer objects not just plain strings. 

oh just in case there was confusion when I say properties, I meant JavaBean
properties and thus attributes in build.xml not <properties .../> elements :P.

>The way to
>go for attributes (IIRC) was to use classes with a constructor taking
>a String object as its only argument.
>
>Say you have a task Foo with an Attribute named bar of type Baz then
>you would need:
>
>public class Baz {
>    public Baz(String value) {...}
>    ...
>}
...snip...

okay ... sounds good for user created types but how about standard types in
java library .. it would mean that you have to restrict properties to new
classes you are willing to define but I guess that may not be too much of a
problem except for the primitive type wrappers ...

>I don't know what to do with the processing part of your idea
>though. I view this as very tightly coupled to the task at hand in
>most cases - with the exception of file lists maybe, but then using
>DirectoryScanner seems a reasonable approach to me. I'm not convinced
>that moving the processing out of the individual tasks into Ant's core
>would be a good idea.

perhaps not sure ... but howmany wrapper classes will there end up being.
Currently I factored out a lot of functionality from other classes (like
package listing from javadocs task) and am seeing repetition of same
calling over and again in my own tasks. This led me to believe there has to
be a better way ... not sure if this is it thou. I just hate seeing the
same two lines or copied methods all through my code 

>
> PD> Request 2:
>
> PD> Would it be possible to have a bunch of standard ant properties
> PD> in Tasks that effect project in other manners.
>
>We should have properties that are named and used in the same way
>across different tasks. Other than that I don't think I understand
>what you mean. 
>
>Your example would be tied to the Javac and maybe the Java task, so
>let's make sure they use the attribute classpath consistently.

unfortunately classpath usually has to happen *before* task is loaded .. ie
you have to load the task through the new classloader .... you can hack it
now (which is what I do :P) by either recursively delegating to another
task or starting a new vm.

> PD> Request 3:
>
> PD> This would allow a single build file to compile the taskdefs it
> PD> needs and then use those in turn to do further processing.
>
>That is you want to build the Task and use it in the same build file,
>right? I've never thought about doing something like this
>myself. Maybe you are trying unusual things 8^)?

probably .. I am not sure it is a good idea thou .. just throwing thoughts
out really :P

>
> PD> Request 4:
>
> PD> A standardised set of taskdefs for invoking standard C/C++ tools
>
>I think after Ant has settled there will be some kind of library for
>optional tasks - hopefully somewhere under the Jakarta umbrella but
>not necessarily in the same repository. I view things like this as
>prime candidates for "standard optional tasks" i.e. optional tasks
>with an implementation from the Ant developers.
>
>A draft on how to handle optional tasks in future versions of Ant can
>be found in spec/core.html again.

off to have a look ...

But before I go there is another Request that I forgot to mention (that is
not patently absurd :P). That is that input and output get wrapped before
each task executes. Some of my tasks produce excessive verbose output that
I can't really hide. I can't hide it as I often delegate to classes that I
don't own or to native apps. 

So what I would like to see is to replace System.out with a custom
PrintStream before execution. This PrintStream buffers output until end of
task. If the task ends in error the output is printed out but otherwise it
is silenetly ignored. This behaviour can be modified by properties ... err
attributes of the task element such as 
<some-task ant:force-output-display="true" .. /> or something similar.
While this could be done in the task it is useful to multiple targets and
should possibly placed in core ???


Cheers,

Pete

*------------------------------------------------------*
| "Nearly all men can stand adversity, but if you want |
| to test a man's character, give him power."          |
|       -Abraham Lincoln                               |
*------------------------------------------------------*

Re: [RFE] Richer Task Specification

Posted by Stefan Bodewig <bo...@bost.de>.
>>>>> "PD" == Peter Donald <do...@mad.scientist.com> writes:

 PD> What I would like is some method of knowing how to preprocess
 PD> properties so that they are in form task wants.  [...]  This
 PD> would also mean it would be possible to have properties that are
 PD> not strings and in fact could effectively be any Object.

Peter, take a look at spec/core.html. Some things you want are already
there, some things have been discussed and even been agreed on but
unfortunately the document hasn't been updated to reflect this.

Basically it has been agreed that project properties as well as task
attributes should be richer objects not just plain strings. The way to
go for attributes (IIRC) was to use classes with a constructor taking
a String object as its only argument.

Say you have a task Foo with an Attribute named bar of type Baz then
you would need:

public class Baz {
    public Baz(String value) {...}
    ...
}

class Foo extends Task {
    ...
    public void setBar(Baz value) {...}
    ...
}

and the conversion would be done automatically. Additionally simple
types could be used as well. I can't remember whether there has been
agreement on how to get the same functionality for project properties.

So this approach is similar to your Converter idea but without the
need for a registry. I realize it is more limited in one way, that is
you can only convert from String - but that seems fine to me as the
values are going to be specified in the build.xml file as strings.

I don't know what to do with the processing part of your idea
though. I view this as very tightly coupled to the task at hand in
most cases - with the exception of file lists maybe, but then using
DirectoryScanner seems a reasonable approach to me. I'm not convinced
that moving the processing out of the individual tasks into Ant's core
would be a good idea.

 PD> Request 2:

 PD> Would it be possible to have a bunch of standard ant properties
 PD> in Tasks that effect project in other manners.

We should have properties that are named and used in the same way
across different tasks. Other than that I don't think I understand
what you mean. 

Your example would be tied to the Javac and maybe the Java task, so
let's make sure they use the attribute classpath consistently.

 PD> Request 3:

 PD> This would allow a single build file to compile the taskdefs it
 PD> needs and then use those in turn to do further processing.

That is you want to build the Task and use it in the same build file,
right? I've never thought about doing something like this
myself. Maybe you are trying unusual things 8^)?

 PD> Request 4:

 PD> A standardised set of taskdefs for invoking standard C/C++ tools

I think after Ant has settled there will be some kind of library for
optional tasks - hopefully somewhere under the Jakarta umbrella but
not necessarily in the same repository. I view things like this as
prime candidates for "standard optional tasks" i.e. optional tasks
with an implementation from the Ant developers.

A draft on how to handle optional tasks in future versions of Ant can
be found in spec/core.html again.

Stefan