Following from Berin's recent post on the subject of lifecycle extensions - I though it would be a good idea to present some thoughts and experience I've had in terms of thinking, dealing with, and implementing abstract lifecycle stages and a proposal to enhance what we already have.


First of all, there are two separate and distinct deployment phases that we are concerned about:

 * component type deployment
 * component instance deployment

When we create a new class instance (e.g. m_classloader.loadClass( "Whatever" ) ) - the JRE is providing class deployment beyond the scenes. This includes things like locating the class bytecode, building the class definition, and validating the class before returning the class to the client. I figure we are all aware of the ClassNotFoundException which is simply declaring failure of class deployment due to a missing definition. The less well known exception NoClassDefFoundError is thrown when you attempt to load a class that has a dependency on another class and the dependent class is not found. The are bunch of other errors that can occur - the point is that the construction of a valid class is a process of class deployment.

When we combine a class with component meta-info we need to also think about the implications this has on component type deployment. For example, a component type may declare lifecycle stage dependencies, context management dependencies, context entry dependencies, and service dependencies. As far as component type deployment is concerned - a container could go through the process of pre-assembly of the classes needed to handle all of these dependencies - validating that classes are accessible, validating semantics such as class assignment to an interface class and so on. On completion of component type deployment we know that instance level deployment is possible.

Object deployment is handled inside the JVM (e.g. MyClass.newInstance() ) A container supplements instance creation with lifecycle stage processing. Lifestyle management concerns the application of a series of ordered lifecycle stages to a component. These stages and their ordering are defined by the framework contracts. From the point of view of a container implementation - two of these stages (initialization and disposal) were semantically extended through the introduction of the concept of lifecycle extensions. While lifecycle extension implementation is largely linked to the excalibur-lifecycle package, the notion of stage is more abstract. As Aaron pointed out not so long ago - there are usage cases for lifecycle stages that do not necessarily interact with the component under deployment. There are other lifecycle stage use-cases which are independent of excalibur-lifecycle in use today in Merlin as part of overall approach to non-Avalon component management (i.e. stage extension unrelated to initialization and disposal).

To fully understand the lifecycle stages and relationship between tags, tools, meta-info, containers and components, we need to consider what abstract is being address at the resolve level:

|------------------------------------------------------|
| @avalon.stage   | Declares that a component type     |
|                 | has a deployment dependency on     |
|                 | a lifecycle stage.                 |
|-----------------|------------------------------------|
| tool            | A container specific tool can      |
|                 | perform static validation relative |
|                 | to the containers stage management |
|                 | strategy.                          |
|                 |                                    |
|                 | Existing tools simply provide for  |
|                 | the generation of <stage> element  |
|                 | with a meta-info descriptor (or    |
|                 | serialized object) that declares   |
|                 | abstract stage dependency.         |
|-----------------|------------------------------------|
| container       | As part of type deployment a       |
|                 | a container can apply default or   |
|                 | or container specific logic to the |
|                 | resolution of a mechanism through  |
|                 | a stage dependency is resolved.    |
|                 | Currently the stage dependency is  |
|                 | urn and a set of attributes.  The  |
|                 | urn identifies an extension        |
|                 | descriptor.  Mapping of an         |
|                 | extension implementation is a      |
|                 | container concern.                 |
|-----------------|------------------------------------|
| component       | A component is passive participant |
|                 | in that is may or may not share    |
|                 | any interaction with a lifecycle   |
|                 | stage. Normally, a component       |
|                 | implementation will implement some |
|                 | interface through which an         |
|                 | extension will interact.           |
|------------------------------------------------------|

From this context, there are some improvements that I would like to see to the excalibur-extension package. These improvements are totally independent of the tag model or meta-model.

The excalibur-lifecycle extension package is our first cut and dealing with one small aspect of dealing with lifecycle stage customization. Through experience a number of things have been learnt. Firstly, the existing interface Create actually handles two phases - component deployment and decommissioning. These two separate concerns should be broken out into separate interfaces. Secondly, the operations defined in the interface imply that a component must be contextualizable. This creates an unnecessary overhead on a container. A short-term solution is to add operations that do not take a context object as an argument. In the longer term, the solution IMHO is to supply a meta model instance such that an extension is simply an abstract extension point (but that's a while away so perhaps my short-term comment is premature).

Evolution of excalibur extension that I would like to see introduced:

1. redefine Creator to aggregate two new interface:

  public interface Creator extends
    DeploymentExtension, DecommissionExtension{}

2. define DeploymentExtension such that is consistent with the existing Create interface and supplement it with non-context and non-object related operations.

  public interface DeploymentExtension
  {
      void create(); // new
      void create( Object object ); // new
      void create( Object object, Context context ); // compatible
  }

3. do the same thing with DecommissionExtension

  public interface DecommissionExtension
  {
      void destroy(); // new
      void destroy( Object object ); // new
      void destroy( Object object, Context context ); // compatible
  }

To conclude - what I have tried to describe here is the separate levels of abstract that exist with respect to lifecycle stage management - from abstract dependency declarations via the @avalon.stage tag, propagation of that abstract dependency via tools to a meta-info model, solution management within a container, and lastly, suggestions for improvement and optimization of the default implementation strategy.

Cheers, Steve.

----------------------

Stephen J. McConnell
mailto:[EMAIL PROTECTED]
http://www.osm.net

Sent via James running under Merlin as an NT service.
http://avalon.apache.org/sandbox/merlin




--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to