ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Donald <>
Subject Re: FW: cvs commit: jakarta-ant/proposal/myrmidon/src/testcases/org/apache/myrmidon/components/deployer
Date Wed, 06 Feb 2002 12:10:18 GMT
On Wed, 6 Feb 2002 13:29, Adam Murdoch wrote:
> > So instead of directly exposing the insides of service you
> > instead expose an
> > adaptor. And then the tasks can change the adaptor to their
> > hearts content
> > for every user request without effecting the core service. So in
> > a way it is
> > making it possible to decouple the service from the task so that they can
> > evolve independently as needed.
> >
> > Thoughts? Do you like this or is it too many layers? ;)
> I reckon it's a good approach, but you're going to have to explain it a
> little more.  I'm not entirely sure which bit you're calling the adaptor. 
> What would it be in the case of the Deployer service and def tasks?

Okay basically I see the parameters to services being used solely by the 
service and never exposed directly in the XML format. For instance just say 
the service needs a list of files. Instead of passing a FileSet object you 
would instead pass an array of File objects. 

The reason for this is that when you need to change the XML representation 
(of the FileSet) this will not effect the service. So the objects that 
reporesent XML constructs are decoupled from the objects that implement the 
service/actual work. 

This allows us much more flexability in changing the XML adaptor objects but 
keeping clean interfaces to the services object.

> It would be handy if you could work through a few examples of how you see
> services working.  How about these:  Using the exec manager to run an
> external command, 

Okay the best example for this may be to look at the CVS task in antlib.cvs 

The task internally uses the Execute2 adaptor object and the Commandline 
adaptor objects. The Commandline object is used to create an array of 
argument for command. The Execute Adaptor object is used to actually run the 
command. The Execute object is actually responsible for then constructing the 
ExecMetaData object and executing the ExecManager service.

Both of these objects are basically there to make life easier for task writer 
and also can be possible exposed in XML representation.

However if you wanted to use the ExecManager without using these adaptor 
objects then that is perfectly fine aswell. If we find out later on that 
there is an easier way for task writers to write stuff we can simply write a 
new adaptor object and away we go - without effecting the service interface.

> using the java compiler manager to compile a bunch of
> files, and using the deployer to deploy something from a typelib.  What do
> the service interfaces look like?  What gets passed across?  How do the
> tasks evolve without affecting the services? 

> How do the tasks deal with different service implementations? 

They don't :) There is only implementaion of each service. For cases like the 
JavaCompiler service which may have JikesCompilerAdaptor, 
JavacCompilerAdaptor and so forth these are largely considered implementation 
details of the service. You could pass in a flag into the service to say that 
you want to use the "javac" adaptor or whatever but it is up to the service 
to implement this. Not sure if that makes sense or not ? ;)

> How does the user pass implementation
> specific properties to the service?

Passing parameters into service.

For the initial configuration/creationg of the service then that I don't know 
- we may be able to configure them when they are registered or maybe via a 
build file - not sure.

> It probably also worth running through what I was planning to do with the
> Deployer, defs tasks, and services:
> First up, some terminology.  I call anything contained in a typelib a
> "type", whether it's a service, task, data-type, converter, project
> builder, whatever. 


>  Types are categorised into roles (whether roles are
> flat like they are now, or heirarchical, doesn't matter).  As far as
> deployment goes, the role determines:
> * How the type should be deployed.
> * What properties are required in its definition.
> Type definitions are built in the following ways:
> 1. The deployer builds a type definition from the typelib descriptor (a
> file). 2. A def task builds a type definition from the build file.
> 3. Type definitions are *not* built programmatically.
> I chose to combine the meta-info and the type definition into a single
> object - a bean (TypeDefinition and sub-classes).  The role deployer
> component creates the bean, it gets configured, and then passed back to the
> role deployer component.  Of course, I hadn't finished implementing this,
> so it wasn't real clear what the intention was.  I don't really care how
> the meta-info and the definition are represented.  We could even axe the
> meta-info, and simply pass a Configuration object through to the role
> deployer component.

Sounds good I think ;) However I would like the TypeDefinition to be 
immutable so that all parameters are passed in via constructor. 

> Absolutely.  But putting the service definitions in a separate file doesn't
> help you deploy them.  It's just another thing to bother with when you're
> assembling typelibs.
> If we do go with the meta-info model above, then it makes sense to put all
> the 'types' (whatever we want to call them) in one spot.

I diagree ;) Think of 

Roles == interface
Type == implementation of an interface
Service == instance of a type

Service has per-instance configuration data which none of the other 
categories of object do. As the number of services deployed in any ant 
instance is going to be extremely low (unlikely that anyone who is not 
modifying the container will even need to create new services) - thus I would 
prefer to keep this separate - at least for now. If we find it is not the 
case in the future we can always change it.

> > > * I'd like to axe the <converters> element in
> >
> > ant-descriptor.xml, and move
> >
> > > the converters to the <types> element.
> >
> > How do you plan to integrate them exactly ?
> As above.  The problem I have with the current descriptor syntax, is that
> the <types> element contains definitions for *everything* in the typelib
> except for converters, which are in their own <converters> element.  So the
> semantics is blurry - what's so special about converters that they need
> their own element?  Nothing, once you take into account all the other
> things that end up in the <types> element - data-types, tasks, project
> builders, build listeners, aspects, etc.

yep - I hate that bit too ;)

> I'd like to clean this up a little by either:
> * Moving all 'type' definitions in the <types> element, so that converters
> would go there, as would any new 'types' that we add later (e.g. services).
>  If we did this we might rename the element <content> or <manifest> or
> whatever.
> * Replacing the <types> element with a top-level element for each role, so
> we would have <data-type>, <task>, <service>, etc elements, with the
> definitions inside.  Something like:
> <antlib>
>   <task>
>     <property classname="..."/>
>     <fail classname="..."/>
>   </task>
>   <type>
>     <fileset classname="..."/>
>   </type>
>   <projectbuilder>
>     <ant classname="..."/>
>   </projectbuilder>
> </antlib>

Both good ideas - I think I would prefer the first over the second but we can 
try both and see which works out better ? It is all automagically generated 
by XDoclet now anyways so change should n't be too hard if we have to ;)



"The only way to discover the limits of the possible 
is to go beyond them into the impossible." 
                             -Arthur C. Clarke

To unsubscribe, e-mail:   <>
For additional commands, e-mail: <>

View raw message