Eike Stepper wrote:
"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]



Reply via email to