avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stephen McConnell <mcconn...@apache.org>
Subject Re: [merlin] concepts, embedding fortress
Date Wed, 18 Jun 2003 12:14:11 GMT

Leo Simons wrote:

> Block Engine Configuration
> --------------------------
> on
> http://avalon.apache.org/sandbox/merlin/meta/model/block/container/index.html 
> it reads: "An engine is an extended classloader."
> that does not make sense to me. I would call it "classloader": 

Yep, I agree.

This is also consitent with some refactoring I would like to see (namely 
seperation of the appliance repositories, and jar extension logic from 
the classloader).

> <classloader>
>   <classpath>
>     <repository>
>       <resource id="tutorial:composition-api" version="1.0"/>
>     </repository>
>   </classpath>
> </classloader>
> also, what is the actual difference between
>   <engine>
>     <library dir=".">
>       <include name="dist">
>       <include name="lib">
>     </library>
>   </engine>
> and
>   <engine>
>     <classpath>
>     <fileset dir="./dist">
>       <include name="*.jar"/>
>     </fileset>
>     <fileset dir="./lib">
>       <include name="*.jar"/>
>     </fileset>
>     </classpath>
>   </engine>
> ? IIUC, the <library/> directive can contain lifecycle extension 
> declarations, whereas the normal <classpath/> does not. So 
> <classpath/> is about making stuff available to components in a block, 
> and <library/> about making stuff available to the block's container 
> (where the container also gets access to the <classpath/> stuff). Right? 


The <library> declaration is simply the declaration of a directory in 
which you have "jar extension jar files".  This is the same notion as 
the java -Djava.ext.dirs except that it packaged with and only visible 
within the scope of the classloader (engine) in which it defined.

> I'd just state it like that, and change <library/> to 
> <container-classpath/> or something similar. Perhaps having a 
> <classloader/> and a <systemclassloader/> containing PATH-like 
> structures. 

Path structures inside a classloader defition are problamatic because 
they result in physical paths in block defintions.  This was the reason 
for the introduction of the <resource> tag - a better approach that uses 
a logical repository.  The objective with the repository approach is to 
enable repository chains and repository policies (but that's all future 
stuff). Part of the rationale here is that something like a war file can 
be considered as the structural element of a repository implementation.

However, the fileset structures are handy during development (which is 
why they are available).

> .xprofile and block.xml
> -----------------------
> I started changing the samples, but it occured to me that the rule is 
> "everything that can be defined in the .xprofile can be overriden 
> inside the <component/> element of a block.xml". What should be added 
> is what the rules are for overriding/merging those, and then the 
> .xprofile settings seperated out. Right? 

Not sure if you saying "should be added to the documetation" or "should 
be added to the implementation".  Currently profiles exist only as a 
facility enabling automated assembly (pre-packaged deployment 
information).  A <component> tag is simply declaring a new profile 

There have already been requests for things like component directives by 
reference to a profile (e.g.):

   <component name="fred" profile="secure"/>

Or, customizing a packaged profile:

   <component name="fred" profile="secure">

> Where do I find those rules?

There isn't a formal model for rules related to what is and isn't 
modifiable reative to profiles.  I have been thinking about this on and 
off with respect to the JMX stuff. For everything in the meta-data model 
(all of the directives) we really need additional information about read 
versus writable, and probably some additional typing and consttrraint 
info.  The biggest job is dealing with configurations and enabling 
arbitary configuration data.

> Custom containers
> -----------------
> Embedding fortress is the goal. Step one is including it as a 
> component. That works of course, but I want the components hosted in a 
> fortress container exported and available to its peers in some way. 

If the component type defition includes the declaration of some 
services, these services will be available to other components.  I.e. 
for a particular application scenario where the services that are 
provided by a component are know at compile time - you just use a 
component.  However, my guess is that you want to have the services 
available from you component as a function of the configuration of the 

Moving on to the example:

> IOW, I think I want something like
> <block>
>    <info>
>      <name>merlin-fortress-interop-demo</name>
>    </info>
>    <implementation>
>      <engine>
>        <classpath>
>          <fileset dir="lib/fortress">
>            <include name="avalon-fortress-complete-1.0.jar"/>
>          </fileset>
>        </classpath>
>      </engine>

A little off-topic but I would recommend using the following:

           <resource id="whatever:avalon-fortress-complete" version="1.0"/>

This change simply means that merlin will attempt to locate the jar file 
from the jar repository.  The current implementation defaults to a file 
based repository located in the merlin installation.  The repository 
follows the same pattern as the maven repository.

>     <container name="fortress"
>         class="org.apache.avalon.merlin.fortress.FortressContainer">
>         <configuration>
>          <class>org.apache.avalon.fortress.impl.DefaultContainer</class>
>          <xconf>
> <!-- fortress.xconf contents here -->
>          </xconf>
>          <xlog>
> <!-- fortress.xlog contents here -->
>          </xlog>
>         </configuration>
>      </container>

The difference between a <container> and a <component> concerns the 
container side management.  There is nothing different on the component 
side except that the component implementation has access to the engine 
via the context interface.  In your example you don't need the engine 
bacuase fortress is doing the deployment stuff therefore you should use 
the <component> directive.

In either case (component or container), if you want to provide the 
Merlin assembly system with information about available services that 
are established dynamically.  The assembly system get this information 
from Appliance.getServices().  The appliance is a regular component that 
is supplied with the deplyment information (configuration, etc.).  An 
implementation would use the configuration information (roles files etc. 
in the Fortrress case) to build the descriptions of the services it is 
capable providing. 

>     <component
>        name="test1"
>        class="tutorial.FortressCallingComponent"
>        activation="startup">
>        <dependencies>
>          <!-- what does this look like??? -->
>          <dependency key="somethinghostedinfortress" type="Component1"/>
>        </dependencies>

Merlin takes care of dependency resolution automatically.  If "test1" 
needs a service then merlin will take care of resolving that dependency.

>      </component>
>    </implementation>
> </block>
> where o.a.a.m.f.FortressContainer creates a Context that is passed to 
> f.impl.DefaultContainerManager to set up a f.impl.DefaultContainer. 
> Idea is simple, how to do it is very blurry. For example:
> - what is the minimum contract o.a.a.m.f.FortressContainer should support?


Literally - nothing.  A container implementation of the component side 
is a completely passive entity relative to the Merlin internals.  It can 
do whatever it likes.  The only real difference is that is has access to 
other appliance instances and as such it can do a lot more dynamic stuff.

> Clearly, it will not do everything a 'normal' merlin container 
> instance does. For example, it's not going to support stuff like 
> container nesting. It's just going to provide whatever it is that 
> fortress provides. 

Which is why it should be declared as a <component>, not <container>. If 
you declare it as a container then you containment side appliance has 
additional responsibilities including handling nested components, 
containers, includes, etc.

> - what interfaces should it implement besides Container? 

It can implement any interface - its just a component.

> The Container interface is all but empty; that can't be right, can it?

A container can be anything you want it to be.  Because this is on the 
client side (relative to the container) - you are completely freee to 
define whatever you want independently of any Merlin API. 

> - what's the deal with the Merlin DefaultContainer and StandardBlock? 
> There's next to no implementation in DefaultContainer, yet this works 
> in 'some' way 'somewhere'. 

The DefaultContainer doesn't need to do anything because all of the work 
is done behind the scenes in StandardBlock. DefaultContainer includes 
meta-info that tells the assembly system to use StandardBlock as its 
containment side manager.  You would do something similar with a dynamic 
Fortress solution - declare the appliance class to use inside the type 
descriptor, provide an implementation of appliance to do the dynamic 
service info establishment based on the supplied configuration, and 
that's about it.

> I have a feeling I'll be wanting to tell lots of assembly and 
> appliance stuff to keep out of the way... 


Throught the Merlin system there is a strict seperation of 
"containement" concerns from "component". Given that the services that 
the FortressContainerwould be providing would be a function of its 
configuration - you are taking about computation that is happening on 
the container side.

To make this easy, I have been thinking about putting in place an 
AbstractAppliance - something that contains default implementations of 
everything such that all you need to do is grab the supplied 
configuration and override the following methods:

  ServiceDescriptor[] getServices();
  Object resolve( Object source, String ref );

The getServices() method would simply build an array of 
ServiceDescriptors using the information from the configuration supplied 
to the appliance.  The resolve method would return service references 
based on the fortress implementation.

> a few pointers would be nice :d 

Hope the above helps.
Let me know if you want to go ahead with the appliance approach and I'll 
refactor things to get in place an AbstractAppliance.

Cheers, Steve.

> g'night,
> - LSD
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
> For additional commands, e-mail: dev-help@avalon.apache.org


Stephen J. McConnell

Sent via James running under Merlin as an NT service.

To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org

View raw message