Gary Shea wrote:
Hi Steve -- Now we're getting somewhere!
:-)
[2002-11-14 02:31 +0100] Stephen McConnell ([EMAIL PROTECTED]) wrote:Correct - however, I think this is inherintly problamatic as it eliminates the possibility for a component to use two service that happen to implement the same interface. I'm guessing - but it does seem that I'm the probably the only one here who is holding out on this example of what has been refered to as a best practice. In my opinion, the best practice is to be explicit and to take the time to document the fully dependency information which means interface + version together with good documentation about the semantic attributed to a service interface version.
Hi Gary:Let me restate this as I understand it. With manual assembly, the
See notes in line.
Gary Shea wrote:
Hey Steve --No problem.
I'm getting merlin to work for me, a little at a time. If I can ever
get all the way there it'll be great! I've got myself pretty stuck at
the moment, need some feedback.
As I mentioned before, the UI is considered a component in this app.Just a comment here - when providing one component as a service to
In my current hand-lifecycled version, I have a giant ugly method in
which all the ui 'controllers' are created as components, one by one, in
a depth-first order wrt the tree of Swing UI relationships. Suppose
component X is responsible for displaying Y. First Y is fully lifecycled,
then X is fully lifecycled, with Y as part of X's context.
another component, you should really be using the Serviceable interface.
While Serviceable and Contextualizable are computationaly similar -
there are some import differences. First of all in you case, presumaby
you component Y is implementating a service oriented interface which is
required by component X. If your assemblying these components manually
(i.e. building the context and service manageme object your code), and
if your following the framework patterns, you would create an instance
of DefaultServiceManager and add component X to the manager under a role
name that Y will use to reference it.
E.g. component X implements a TimeService interface and component Y is a
Scheduler that has a dependency on a service implementing the
TimeService interface. The scheduler should use the Serviceable
interface, under which it is supplied a ServiceManager, and from which
it can lookup the time service with a key.
In this scenario, your lifecycle handler you need to know the role name
to assign for the different services, and all of your components would
need to be careful about using the same role name. That's ok in a
limited scenario - but what is even better is if your utility can get
the class of the component it is processing, get a bunch of meta
information, and derive from that the service defintion and role name
that the component needs. This is achieved through the structures in
the excalibur/meta package - "the xfiles". The file named
<component-classname>.xinfo should contain a <type> element as the root,
and within this you can declare a depedency (e.g. the .xinfo for X would
declare a dependency in a time service, and component Y would declare
that it porvides the time service. If you package this information
within "x-files" your application becomes more loosely coupled because
you don;t have to follow strinct naming conventions, and keys used to
lookup services can be scoped locally within the depedency defintion of
the consuming componet.
DefaultContext and DefaultServiceManager objects are created by hand for
each component that will be deployed. That code must have the text of
the key, meaning that to be reasonably safe the key is a public static
somewhere.
On the other hand, with automated assembly, the key is in
the .xinfo files instead of the code. I prefer that too. It's probably
a slight loss of safety since there's no consistency constraint
equivalent to the public static key that's visible everywhere in the
classloader scope, but it reduces coupling in the code, which is a very
highy priority.
Yep - good assessment of the pro and cons.
It had occurred to me switching to Service might get it, but hadn'tYep - one other thing to be aware of is that the Serviceable interface implies an additional obligation. Services aquired though a ServiceManger should also be relased back to the manager. Keep in mind that a container is putting a lot of effort into respecting lifestyle policies that object implementations assume. To propoerly respect something like a pooled policy, you need to declare to the container that you have released the service in question. The container receives bnotification of the release of a service via the ServiceManger's release operation and from that can free up resources no longer required, or other optiimization functions.
gotten to do the experiment yet. Glad to hear I'm on the right track.
Current documentation on the context directive at the profile level could be improved - what is there currently is minimal and bunch more stuff is needed to detail all of the fun things you can do with parameters, nested parameters, referencing existing context values as parameter arguments, etc.
Ok, enough rambling about that - except to say that all of the above isYep, with you so far ;)
addressed in the excalibur/meta package and really havn't got into
Merlin space yet.
I think the reason my method doesn't want to work with merlin is that aLet's ignore the fact that your example talks about putting a service
mapping needs to be created automatically from a deployed component to a
context key value! How could merlin know that?
into a context object and assume instead that your dealing with the
problem of populating a context object automatically. At the component
meta level (excalibur/meta) you can declare that the component instance
implemets an interface derived from the framework Context interface (if
nothing is declared for a context type then the framework Context
interface is assumed). You can also declare in the .xinfo file
<context/> element the entries to be included in the context. Context
entries include the declaration of the class of the object that is
expected, the context key the component will use to access the context,
and if the context entry is required or optional.
If we move up to the next meta level (refer excalibur/meta/model) youYeah, I'm declaring a context value in the profile now. It makes sense.
have the Profile class. The profile class contains a much of structures
called directives which let you build an object model of the parameters
to be supplied to a component during lifecycle processing. For the
context object the Profile type includes support for the declaration of
a ContextDirective. A ContextDirective lets you declare two form of
context value aquisition:
* importing a context from a container using a container scoped key
* declarative construction of a context object using parameters
I'm still not entirely comfortable with Profile, although I suspect
that's largely because the doc is not complete yet and I am not yet
familiar enough with the code.
I like using it but am still closing inYour example is the application of <component/> as a directive within a container - which is basically telling Merlin "take this information and build a type then build a profile referencing the type, the create an instance based on the profile, and locate the instance within the enclosing container".
on feeling like I know what I can do with it. I think that's because
the profile is a combination of three kinds of information:
Data which is truly meta wrt the .xinfo contents:
+ the presence of a <component/> directive is metainfo telling
merlin to deploy that component in this profile, information you
cannot specify in the .xinfo
The second example of the use of a <component> directive is within an xprofile file. The .xprofile can contain multiple pacaged and named descriptions (profiles) which merlin can use automatically when another component declares a service dependency.
Finally (although not implemeted yet) would be the referencing of a packaged component profile from within a container.
E.g:
<component type="MyComponent" profile="persistent"/>
Or:
<component type="MyComponent" extends="persistent">
<configuration>
<connection jdbcdrive="whatever"/>
<cofiguration>
</component>
Its more correct to say that this is data that that fulfilling criteria exressed at the type level.Data which is independent of the .xinfo contents: + can specify context keys and validation info in the .xinfo, can specify values in the profile
For example - the .xinfo declares that a context entry keyed to the name "avalon:home" must be provided and the type of argument must be a javalio.File. At the profile level you my see an import or constructor directive which is satisfying the type level criteria.
type + class <--- establishes the crieria
profile <--- populates the criteria
Data which overrides .xinfo contents:Configuration - yes - assuming the typoe has a packaged default configuration.
+ configuration
+ categories
Categories - no. Category declaration is a directive that assign things loke the logging channel priority, logging target, etc. Wheras the type level information is purely the declaration that a named logging channel is required. Again, this follows the seperation of criteria for fullment at the type level, directives supporting fullfilment at the profile level.
Have I got that right?You have me thinking if it would be a good idea to introduce a seperate profile tag, which would better seperate the notion of the component tag as a directive. For example:
<component type="MyComponent"activation="startup">
<profile name="default-authorization">
<!-- other profile stuff -->
</profile>
</component>
This does not sound right.Using the excalibur/meta APIs, you can introduce a much higher degree ofAgreed.
loose-coupling into your lifecycle utility. You can even take avantage
of preconfigured profiles and default configurations - which make life
*much* easier for the end user.
Just for clarification - here is the basic seperation that theMany profiles may be declared for a particular type? My understanding
excalibur/meta package provides, and the seperation I'm working on with
respect to synchronizing merlin with the excalibur/meta.
Type Level
An API supplimenting class information with details about
required dependencies, and extensions, service the
component provides, context and logging constraints and
type-level defaults.
http://jakarta.apache.org/avalon/excalibur/meta/type.html
Profile Level
An API that allows the capture of different deployment
profiles - where a profile is a combination of configuration,
context, parameters and logging information. It is possible
for may profile to be declared for a particular type.
http://jakarta.apache.org/avalon/excalibur/meta/profile.html
is that multipe profiles may be declared for a particular application,
each of which may assemble a particular Type in a different way. Is
there a way to say "for type X use profile P"? That sounds like a
meta-profile!
Imagine you have a component that provides a persistence service. That component implementation may provide support for multiple persistence solutions (memory based for testing, file based for convinience, database for scalable deployment). Each one of these deployment scenarios could be pre-packaged as a named profile using the <classname>.xprofile resource. During the assembly process, the assembly engine calls in a selector (which a component or container can customize). While explict references to profiles in a <component/> tag isn't isn't available yet, its possible to achieve the same thing using a custom selector (a helper that kicks in during resolution of multiple candidates during the assembly phase).
Whereas an "application profile" would be much closer to a container directive. Because an application is in effect defined by the assembly of profiled components within an application context established by things like the container's classloader, etc.
Yep - hole in one.Appliance
An applicance (not in CVS yet but part of the refactoring I'm
doing in merlin to sync. with excalibur/meta updates) represents
an assembled profile and the access point to the services that
a type provides. Appliance also encapsulates lifestyle
management because this is the object that is used to actually
get an instance of a service.
[no doc yet - working on it]
This is a hard concept to put a word to because it's two things at once, right? The factory part which is about meta-info, and the lifestyle management which is about meta-state. So the the final object which hands over the instance of the service is a lifestyle manager (which maintains meta-state based on lifestyle meta-info), which delegates object creation to the factory (which is a meta-info interpreter)?
Keep in mind that an Appliance is part of the container architecture and would not be exposed to the client. Typically the client will only see service via a service manager and the service manager implementation will interact with the appliance. However, there are lots of cases of code that manually handling the creation of service and context objects because its just plain easier and faster than declaring all of this. In those situations, a nice middle ground is to use some sort of intermidiate utility - and that's the function/role of the Appliance.
Instance
A regualar java.lang.Object, established as a result of a
request to an appliance. The identity of the instance is
a function of the lifestyle policy that the appliance is
enforcing. This object is the service from a consumers
perspective and could be a proxy of the component, a
obnject reference, etc. depending on the type of appliance
that is handling activation.
Ok, you now have my permission to add you name to the "Steve's wordy
email hate list"!
:-)
Not on your life! I will have you know I printed this damn email, it was too big to read on the screen. ;) Very useful too! Thanks for taking the time.
No problem - more questions like this only lead to better system. Cheers, Steve.
Gary
Hope this helps!
Cheers, Steve.
Regards,--
Gary
--
To unsubscribe, e-mail: <mailto:avalon-users-unsubscribe@;jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-users-help@;jakarta.apache.org>
Stephen J. McConnell
OSM SARL
digital products for a global economy
mailto:mcconnell@;osm.net
http://www.osm.net
--
To unsubscribe, e-mail: <mailto:avalon-users-unsubscribe@;jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-users-help@;jakarta.apache.org>
--
To unsubscribe, e-mail: <mailto:avalon-users-unsubscribe@;jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-users-help@;jakarta.apache.org>
-- Stephen J. McConnell OSM SARL digital products for a global economy mailto:mcconnell@;osm.net http://www.osm.net -- To unsubscribe, e-mail: <mailto:avalon-users-unsubscribe@;jakarta.apache.org> For additional commands, e-mail: <mailto:avalon-users-help@;jakarta.apache.org>