ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject Re: Did somebody say Shut up and Write? :)
Date Tue, 26 Dec 2000 23:40:43 GMT

ok, here are my thoughts/complaints/requirements for ant 2.0. JDD's doc is
a great start, and I'd like to get my 2 cents in...
I know I've said this before (and have submitted a prototype for a possible
solution), but we need a way to merge targets from multiple project files
into a single dependency graph. Here are some cases where this might be

1) The user wants to break down a large antfile in smaller ones, possibly
in subdirectories, to simplify things (ie to make stuff easier to find and
to reduce merging).
2) The user wants to pull out code that can be shared with another project.
Both projects should be able to include the subproject as is, without
modifying its antfile (ie changing its "workspace" attribute).
3) The user wants to compile the code from a third party project (xerces,
for example) as part of building their project. The third party project may
or may not be in a subdirectory of the main project.
3) The user wants to load a custom task from another project, and possibly
compile the task before loading. Ideally, there won't be two totally
different mechanisms for this (ie a <taskdef> statement vs an entry in the

The current way to handle these cases is via the "ant" task. However, the
concept of an "ant" task (or an "execute-target" task, as mentioned in
JDD's write up) simply doesn't work for large projects, since large
projects usually consist of graphs (not trees) of subprojects. Ant must be
able to analyze the *entire* graph of dependencies before building, and
dependencies hidden in tasks (and not declared using the "depends"
attribute) prevent this. So your targets basically become functions, and
the result is that targets get built twice, or not at all, depending on how
you've set things up (same as recursive make).
I realize that a lot of people use the ant task to run the same script with
different sets of properties, however. This is basically a poor man's
"template" or "macro" and is not a reason to keep the ant task around - it
just means that we need to come up with a real macro system. The expansion
of these macros should be done at parse time so that by the time the build
phase begins, all of the dependencies can be sorted out. Here are some
examples that I think need to be addressed:

1) The user wants to execute the same set of steps for each subdirectory,
ie compile all the files, put them in a jar with the same name as the
directory, copy the jar to "dist/lib". I believe the netbeans project does
something like this.
2) The user wants to change an attribute for all tasks of the same type, ie
set debug="true" for all javac tasks. Most projects I've seen define a
"debug" property that must be specified in each "javac" task, and is easy
to forget.
3) The user wants to execute multiple tasks with a simple command. So a
"compile" tag might get turned into some "preprocess" task followed by a
"javac" task.

One option is XSLT. It would be powerful and easy to implement, but the
learning curve might be a bit too steep...
I also have a question about the ability for tasks to access the ant object
model. One thing that JDD mentions in his doc is that "the entire build
tree is represented in memory and available to all tasks that run". Is this
really such a good idea? How many tasks actually take advantage of this?

I'd prefer to see a much tighter contract between tasks and their invokers.
The biggest thing ant has going for it is the sheer number of tasks that
have been defined for it. This api should be as small as possible, so that
it's easy to use those tasks in a variety of settings, and to future-proof
those tasks. I'm thinking of something EJB-ish like:

public interface Task {
     public void setTaskContext(TaskContext ctx);
     public void execute() throws BuildException;

public interface TaskContext {
     public void info(String msg);
     public void warn(String msg);
     public void error(String msg);

     public String getName();

Once 2.0 ships, adding methods to the TaskContext interface should be very
difficult and removing a method or changing a signature should be near
impossible. By limiting which methods a task has access to, we can make
sure that the tasks won't need to be rewritten with every release.
Providing access to the entire object model seems like trouble.

I agree, however, that it's handy for a script to be able to manipulate
targets and tasks. But I think this should be done before the build phase
starts (and after parsing), as opposed to doing it from within a task. That
way the dependencies can be sorted out before the build phase (sense a

Matt Foemmel
ThoughtWorks, Inc.

                    James Duncan                                                         
                    Davidson             To:     <>      
                    <duncan@x180.        cc:                                          
                    net>                 Subject:     Did somebody say Shut up and Write?
                    06:05 AM                                                             
                    respond to                                                           

Ok. So, I heard ya. And I've started a write up. If this is an attempt to
actually build consensus on Ant2 and earn my stripes, so be it.  In any
case, Jon was correct in his phone call to me that it was time to put up or
shut up.

View raw message