"Stephen McConnell" <[EMAIL PROTECTED]> schrieb im Newsbeitrag news:[EMAIL PROTECTED]
Eike Stepper wrote:
hi,
what is the preferred way to commission components dynamically?
The preferred way is to use a "facility" - which I'll explain. Currently I'm presuming that you have merlin embedded in an application and you have successfully deployed a block (or two or more) either by parameterizing the factor criteria or by interacting with the root containment model API.
At this level (meaning at the level of code that is embedding Merlin) you will quickly run into limitations as to what you can and can't do as a result of not having component classes available in the space in which your code is executing. The classes are available within Merlin down in a container somewhere but your simply too far removed from action. The solution is create a regular component that will manage things from with (as opposed from above).
i'm not sure about what you mean here. what is the benefit in creating another component with the same inconveniences (regarding the accessibility from outside of the container)? is it not possible to set up the classpath of the "embedder" similar to the one of the container?
Sure it is - but the downside of this is that you code is written in a way that makes assumptions about a classloader context. The alternative is to encapsulate the "assumption" under a block within which the assumption is declared.
The result of pushing this down into a dedicated component is that your code dealing with the establishment of socket handlers can be easily moved between different embedding scenarios because the required classloader context is always mapped into whatever embedding scenario it is running within.
Management from within is archived by providing a component with a reference to the containment model it is resident within. Like Niclas described - this is achieved by declaring a context entry dependency on the component that Merlin will take care of for you:
public class MyComponent { final ContainmentModel m_model;
/** * Creation of a new facility. * * @avalon.entry key="urn:composition:containment.model" * type="org.apache.avalon.composition.model.ContainmentModel" */ public MyComponent( Context context ) throws ContextException { m_model = (ContainmentModel) context.get( "urn:composition:containment.model" );
// and now your playing from the inside with everything // you need in the classloader associated with this // container - you can create and remove subcontainer, // commission and decommission components, change // configurations, whatever .... } }
up to now i just call the constructor of the component class and some of the lifecycle methods. how is the association to a particular container established?
You should *never* need to do such lowly stuff - merlin will do these things for you based on request you make based on supplied service references or named components references. Remember that it's really important to eliminate assumption in you code about components (such as constructor signatures, lifecycles, etc.).
i've also tried to use the model to add a DefaultComponentModel but got stuck when asked for the SystemContext with its awful ctor.
Sounds like your going about the construction of the DefaultComponentModel in the wrong way (which is interesting because it means we have a few constructors to move from public to protected). A ComponentModel (a type of DeploymentModel) is normally resolved by locating an existing component model that was declared within a block under a <component> directive using one of the getModel() operations.
However, if your really aiming for total dynamics and you intend constructing a totally new component. Then you create an instance of ComponentProfile and add this to the container (and the container will return the corresponding ComponentModel):
ComponentProfile profile = createMyComponentProfile(); ComponentModel componentModel = (ComponentModel) m_model.addModel( profile );
no, i'm not looking for the lowest way but for an example of the usual (high-level) way. please imagine a simple tcp connection listener (ServerSocket). on connection attempt of a client it has to incarnate a slave socket. in case this slave socket is a component (i want to manage and monitor it), the master component would have to commision a new component. i could not find any example or description, how this is achieved (well, actually there was an example in excalibur or cornerstone, but that illustrated the direct use of constructors and active lifecycle calls, which you called odd above).
OK - in this scenario it seems to me that you already know the *type* of component you want to commission. In this case you want to instantiate an instance of "slave socket". You can declare the "slave socket" component type using a <component> directive (with startup="false"). Your listener component would declare a dependency on the slave and would request a reference to the slave by invoking lookup on the supplied service manger. If the slave has a "transient" lifestyle policy then you will receive a new slave per request.
As the listener is acting as a coordinator - you slave interface would need some operations to set things like port and so on. Alternatively you could describe a slave factory component that handles the setup of a slave based on some supplied parameters (e.g port, etc.).
Cheers, Steve.
--
|---------------------------------------| | Magic by Merlin | | Production by Avalon | | | | http://avalon.apache.org | |---------------------------------------|
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]