On Sunday 01 August 2004 20:23, David Leangen wrote: > So far, I think this is what Avalon/Merlin is intended for.
So far, I follow... > When dependencies are clear, everything works beautifully! Each service > will fire the services it depends on and all goes amazingly well. What do you mean by "fire"?? Nobody gets fired in Merlin :o) > Where things get messy, however, is when you want to build components from > services that should NOT be dependent, but you want the services to execute > sequentially. (For a good comparison of what I mean here, think, for > example, Ant tasks and they are executed sequentially.) Ok, with the given example of Ant Tasks, the proper model would include all the various Tasks, each having no clue about anyone else. BUT, just as in Ant, they do know that they belong to a Project, so they declare a dependency on a Project service. So, Tasks looks up Project and registers themself there. The Project knows that there must be a Sequencing component (the guy that figure out what Ant can do, i.e. interpreter of build.xml) available, and looks it up. The Project calls upon the Sequencer, and hand it the projectDir (or something) plus the collection of Tasks at its disposal. This is of course greatly simplified, and there are a lot more to it, but I hope that you can see the given example has no major issues, and can be solved fairly straight forward. > It appears that this can be done, but it's not what Merlin was intended > for, so the solution is a hack. Out of the possible solutions that have > been suggested to me are: > > 1. Declare artificial dependencies. This does solve the problem, > but it creates a spaghetti of artificial dependencies that > just shouldn't exist. Again, I think your componentization approach may be a bit 'wild' and perhaps too much 'shoot from the hip', if you know what I mean. Just like procedural programmers (I was one) had a hard time with OO initially, and came up with all kinds of 'problems' that OO couldn't solve, we (I included) finally realized that a slightly different tact of approach was required, but it sure could solve any problem with throw at it (OO). I hope COP is not as big step, but certain ways one think is the way to attack the problem, may look like COP was not meant for, but given a bit of experience and advice, we soon find that there are other patterns involved. > > How can you listen to a component that you don't "know about" (i.e > > no dependency). Please note that the dependency can be declared both > > optional and against very generic interfaces. > > I think what I didn't explain well here is that, reusing my definitions > above, my Component will use two ServiceProviders. So, of course the > Component will "know about" the ServiceProviders, but each ServiceProvider > should not need to know anything about the other. They don't need to. > In any case, the thing is, to me "optional dependency" is an oxymoron. > Either there is a depedency or there is not. A dependency cannot be > "optional". If it were optional, than there is no dependency to begin with! I have a great example in the Http Facility that I am currently working on. There are a few 'optional' dependencies. For instance, if you include an Authenticator it will be used, otherwise the feature is not supported. > Also, declaring to a more generic interface makes sense... but isn't that > what the component-based model in intended for to begin with? I don't understand the syntax in statement. :o( Please elaborate. > 2. Use an event listener to wait for the completion of the services's > execution. Ok, but shouldn't the framework be doing this for me? > What's the point of having a nice framework if I have to go and > make while loops while waiting for an event? This also complexifies > the code, which is not something I want to get into. I have a Event-rich framework dated back to 1997, which I want to port to Merlin, but haven't got around to do. While looking at how to do the port, it dawned upon me that a lot (not all) of the JavaBeans style Event mechanisms are not at all required in Avalon. Often the Event path can be substituted with 'direct' connections in the composition model. All in all, complex applications will end up with less Event-paths with Avalon than without, but not completely free of them. > 3. Make a new service interface for each sequence. Not sure what you were getting at here in (3) > 4. Make a Component that simply directly uses the POJOManagers, rather > than the ServiceProviders. Well, again, this defeats the whole > purpose of using the ServiceProviders, doesn't it? No it doesn't. If you have components that doesn't require Avalon LifeCycle, you can just create the Type information (javadoc tags or .xinfo file) and use them as-is. We do that all the time outselves, especially when adopting existing libraries (like Jetty). > All these work, but none are desireable. Really, the best situation is to > have, within something like the Executable interface, a way of making a > call like: If you are looking for a batch languages, this is not it. :o) Avalon/Merlin is a generic platform, capable of creating batch languages, J2EE servers, banking applications, process control applications, or whatever. It is not tailored to sequence components to get a shot of execution along a timeline. That you have to provide yourself. > THAT would be sweet!! Ok, here we go. public class Sequencer extends AbstractLogEnabled implements Executable, Serviceable { private ServiceProviderA m_ProviderA; private ServiceProviderB m_ProviderB; /** * @avalon.dependency type="org.hedhman.niclas.demo.ServiceProviderA" * key="providerA" * * @avalon.dependency type="org.hedhman.niclas.demo.ServiceProviderB" * key="providerB" * * IF these are the same class, Merlin currently doesn't allow you to * lookup ALL of a particular type. In such case you either need to create * a selector mechanism that allows for this. I.e. create a * ProviderCollection class and look that up and call a getAll() * method or something like that. * OR have manually wired each provider to the respective lookups. (This * manual wiring is often needed in applications with long-term running * instances of the same type connected in various patterns, for instance * process-control applications is full of that.) */ public void service( ServiceManager man ) implements Servicable { m_ProviderA = (ServiceProviderA) man.lookup( "providerA" ); m_ProviderB = (ServiceProviderB) man.lookup( "providerB" ); } public void execute() { m_ProviderA.doStuff(); m_ProvicerB.doStuff(); //done } } Is this considered so damn hard? > But since that doesn't exist, either I'll have to choose one of the above > hacks, or give up on Merlin. "Hacks" is a relative term. If you quantify "any code I have to write to make things happen" = "hack", then yes, Merlin is full of them. If you mean "a tricky way around an obstacle, that only makes my life miserable" = "hack", then I disagree with the term used. I think you are looking for a solution to a particular problem, that Merlin wasn't designed to bother about, and that the solution is a couple of hundred lines of code (which would have been a couple of hundred lines of configuration files otherwise). If 'batch execution' is the 'problem' then the solution is one or a set of Sequencers (and possibly Parallelizers :o) ). I honestly think that you have an inaccurate perception of what is expected out of Merlin, and once you 'see the light', you can afford to laugh at this 'juncture' :o) Cheers Niclas -- +------//-------------------+ / http://www.bali.ac / / http://niclas.hedhman.org / +------//-------------------+ --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]