ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Adam Murdoch" <>
Subject RE: cvs commit: jakarta-ant/proposal/myrmidon/src/testcases/org/apache/myrmidon/components/deployer
Date Mon, 04 Feb 2002 02:46:17 GMT

> -----Original Message-----
> From: Peter Donald []
> Sent: Sunday, 3 February 2002 2:12 PM
> To: Ant Developers List
> Subject: Re: cvs commit:
> jakarta-ant/proposal/myrmidon/src/testcases/org/apache/myrmidon/componen
> ts/deployer
> On Sun, 3 Feb 2002 08:59, Adam Murdoch wrote:
> > > -----Original Message-----
> > > From: Peter Donald []
> > > Sent: Sunday, 3 February 2002 12:17 AM
> > > To: Ant Developers List
> > > Subject: Re: cvs commit:
> > > 
> jakarta-ant/proposal/myrmidon/src/testcases/org/apache/myrmidon/componen
> > > ts/deployer 
> > >
> > > On Sat, 2 Feb 2002 23:51, wrote:
> > > >   /**
> > > >    * A general-purpose type definition.
> > > >    *
> > > >    * @author <a href="">Adam 
> Murdoch</a>
> > > >    */
> > > >   public class GeneralTypeDefinition
> > > >       extends TypeDefinition
> > > >   {
> > > >       private String m_name;
> > >
> > > vs
> > >
> > > >   public abstract class TypeDefinition
> > > >   {
> > >
> > > Is there any need to separate out the above two classes? From the
> > > looks of
> > > things - no - but is there something else you have in mind?
> >
> > Not particularly - I added GeneralTypeDefinition so that I could move
> > setType() and setName() out of TypeDefinition, where they were being
> > inherited by ConverterDefinition (and so visible as attributes in
> > <converter-def>).  Maybe we could rename TypeDefinition ->
> > AbstractTypeDefinition and GeneralTypeDefinition -> TypeDefinition.
> Oh right - now it is clearer. However what I have gone and done 
> is made the 
> TypeDefinition immutable. I would personally like to see that all types 
> passed to a service (which includes passing stuff to deployer 
> from tasks etc) 
> is either made up of primitive types or immutable.
> The reason for this is that a lot of problems in ant1.x is that 
> there was no 
> distinction between responsibilities of task and responsibilities of the 
> "service" and as such methods kept getting added on and causing 
> issues. Also 
> names/ideas/concepts and things kept getting out of sync between 
> the service 
> part and the task part.
> 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?

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, 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?
 How does the user pass implementation specific properties to the service?

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.

This suggests to me that type definitions should be meta-info driven.  All role-specific knowledge
of how to define and deploy the types of a particular role would live in a specialised component,
one per role.  The deployer itself, and the def task, would be general-purpose, and would
use the meta-info provided by the specialised component, to build the type definition.  Here's
how a type would be deployed from a typelib descriptor:

* Deployer determines the role of the type from the name of the element from the typelib descriptor.
* Deployer fetches meta-info for the type definition, from the appropriate role deployer component.
* Deployer builds and validates the type definition, using the meta-info and the contents
of the element from the typelib descriptor.
* Deployer passes the type definition to the role deployer component, which does the work
of deploying the type.

Deploying a type from a def task would work exactly the same, except the role might be determined
differently, and the def task's model is used rather than an element from the typelib descriptor.
 Otherwise the same.

Using a meta-info driven approach is inherently easier to evolve than one which explicitly
models the different type definitions, and builds them programmatically.  We can add and remove
stuff from the type definitions easily, we can change how types of a particular role are deployed,
and we can add and remove roles - all without changing the deployer, or the def tasks.  A
single deployer and single def task would handle every type.

Of course, meta-info driven definitions are a PITA to use programmatically.  If we do find
that we need to build definitions programmatically, then we can expose some of the role-specific
components as alternative services, for example.

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.

So that was the plan.  I don't think it is incompatible with your plans - given that the goal
was to put together a general-purpose mechanism for deploying stuff from both a typelib descriptor
and from the build file.

> > * Add a ServiceDefinition sub-class, and deploy services from 
> the typelib
> > descriptor.  Maybe add a <service-def> task as well.  Need to think a
> > little more about what "deploy services" means.  Any problems 
> with putting
> > the service definitions in ant-descriptor.xml, rather than
> > ant-services.xml?
> I would prefer to keep them separate for now. Deploying services 
> is a fairly 
> different concept to registering types. When you deploy a service 
> you have 
> things like lifecycle management, configuration and so forth to 
> worry about. 
> And services are controlled by the container which is different 
> from types 
> which can be controlled by anyone.

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'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.

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:


    <property classname="..."/>
    <fail classname="..."/>

    <fileset classname="..."/>

    <ant classname="..."/>



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

View raw message