ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Adam Murdoch" <>
Subject RE: [myrmidon] add TaskContext.getService()
Date Sat, 26 Jan 2002 06:14:05 GMT

> -----Original Message-----
> From: Peter Donald []
> Sent: Saturday, 26 January 2002 1:01 PM
> To: Ant Developers List
> Subject: Re: [myrmidon] add TaskContext.getService()
> On Sat, 26 Jan 2002 13:20, Adam Murdoch wrote:
> > > -----Original Message-----
> > > From: Peter Donald []
> > > Sent: Saturday, 26 January 2002 6:59 AM
> > > To: Ant Developers List
> > > Subject: Re: [myrmidon] add TaskContext.getService()
> > >
> > > Also rather than making DefaultTaskContext Composable I just 
> passed the
> > > ComponentManager in via the constructor. Seemed simpler and less
> > > likely to cause problems.
> >
> > Ah good.  I wasn't sure if it was the 'myrmidon way' to make 
> something like
> > this Composable.
> >
> > Any thoughts on how we might add services at runtime?  Seems 
> like we have a
> > few places where service definitions will need to come from:
> I was just thought experimenting with something like this at the 
> moment. My 
> experimentation made the assumptions;
> * services are runtime or workspace wide
> * services may or may not need to be "configured" either with 
> workspace or 
> deployment contextualization info
> * multiple "falvours" of a service are not needed in the same 
> workspace (ie 
> no need to have two different VFSs or ExecManagers or whatever)

Sure.  The question is whether different configurations for a service are needed at different
stages of a build.  Let's say no for now.  Even if that doesn't end up being the case, the
configuration can always be passed as a parameter to the service's work method.

> My thinking basically went along the following lines. We add a 
> descriptor to 
> jars at META-INF/ant-services.xml and looks something like
> <services>
>   <service role="org.apache.ant.VFS" factory="org.apache.ant.VFSFactory"/>
>   <service role="org.apache.ant.ExecManager" 
>            factory="org.apache.ant.ExecManagerFactory"/>
> </services>
> or maybe
> <services>
>   <service role="org.apache.ant.VFS" factory="org.apache.ant.VFSFactory"/>
>   <service role="org.apache.ant.ExecManager" 
>            factory="org.apache.ant.ExecManagerFactory">
>       <some-config-param attribute="2"/>
>        <text>Some textual data...</text>
>   </service> 
> </services>
> So the Factorys would be instance of a certain interface, namely
> public interface ServiceFactory
> {
>   Object createService() throws ServiceException;
> }
> The reason for this extra level of indirection (ie instantiating 
> a factory 
> rather than service directly) is because then it becomes possible for the 
> services not to be heavily integrated into the ant (or avalon) 
> runtimes. They 
> only have to implement the service interface. So we can make the factory 
> configurable/contextualizable or configure it via ants 
> auotmapping features 
> but the underlying service does not need be aware of this. The 
> main reason is 
> because I know there is at least one person who would love to use 
> some of the 
> ant services outside ant ;)

Factory is a great idea.  Not so sure about a separate file - what's wrong with adding service
definitions to the typelib descriptor?

The reason I ask, is that it would be good to generalise the factory idea into the TypeManager,
rather than treating services something special.  This way, any type (task, data-type, service,
project-builder, aspect handler, custom role) can provide either a factory or a class name.
 When a factory is provided, it would be configured using the contents of element in the descriptor.

Also, any chance we can pass in a Context to the factory?

> Anyways I may upload a cutdown version to see what you think ?
> > * A typelib that adds a new service type, may also want to specify a
> > default implementation to use.
> >
> > * The system and user config files, may specify an 
> implementation to use. 
> > The implementation would also need to be configured here.
> >
> > * The build file, may explicitly specify an implementation to 
> use.  Global,
> > and per-task.  Also needs to be configured.
> Im not sure - hadn't really thought about it. Could you give me 
> some examples 
> of why you would want to change any service - I could see the 
> need for adding 
> new services but just not so sure about changing.

There's 2 things the build file needs to be able to specify:

* Which implementation to use.  This could happen globally.  Unless the implementation was
not in a typelib that I could <import> - for example, a C++ compiler adaptor for a compiler
that isn't supported, that I have to build as part of my project.

* Some way to use different configurations for the service in various places.  E.g debug vs.
no debug, emacs mode, etc.  I don't think this is necessary at this stage.

> > It's probably worth doing up a ServiceManager interface, and a 
> hierachical
> > DefaultServiceManager impl.  It would manage mapping between the service
> > interface and the implementation object.  I don't think it's 
> worth having
> > the ServiceManager handle more than one implementation of a particular
> > service.  This way, in any given context, there will be a single active
> > implementation of a particular service.
> ServiceManager == ComponentManager

Sure.  Does it matter that ComponentManager is immutable?

> So if we go this route we may aswell use ComponentManager directly :)
> > We're going to need a Service role, too, so we can instantiate via a
> > TypeManager (i.e. from typelibs).  A hierarchical role/type 
> model like we
> > discussed earlier would be handy here, so we can refine the Service role
> > into roles like JavaCompiler, JavaLauncher, CommandLauncher,
> > FileSystemManager etc.  In the meantime, we can bung them all into the
> > Service role for now.  Which means we need a Service marker 
> interface for
> > the time being.
> Some of them (ie CommandLauncher) have too rigid a selection logic for it 
> useful to abstract it but things like JavaCompiler and EJBPacker would be 
> definite candidates for types being stored in the TypeManager. (However I 
> would still like to think that these types are accessed by a 
> Service rather 
> than the task directly accessing them. Does that make sense ? ;)

Yep.  In fact, we could enforce this across the TaskContext boundary, so that TaskContext.getService(
TypeManager.class ) would return a TypeManager for the DataType role only, nothing else.

> > Adding services in the type library is easy enough - should 
> work right now,
> > if we add a Service role.  It would be a useful thing to introduce the
> > concept of a default implementation to TypeManager/TypeFactory, 
> I think. 
> > It will also come in handy for our general-purpose types, like <path>.
> I tend to think of services as different from types. Services 
> persist over 
> the length of the ant "execution" or at least the "workspace 
> execution" or 
> whatever term we were using for this. Types are created by tasks while 
> serviuces never can be etc.

Exactly.  And that's why they would use different roles, to distinguish between what they
are and how they should be used.  But that doesn't mean the same infrastructure shouldn't
be available to both services and data-types.


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

View raw message