You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Stephen McConnell <mc...@apache.org> on 2003/06/12 09:31:47 UTC
Re: merlin's meta tags and a bigger LCD
Hi Leo:
Good to see your hard at work!
Some agreements and some disagreements in-line.
;-)
Leo Simons wrote:
> Stephen McConnell wrote:
>
>> Only works if we cater for all of the requirements.
>> I.e. the LCD approach fails the usability test.
>
>
> it fails some tests, not all. A LCD is always less usable, but the
> point is that it is still usable. For example, in merlin, versions
> might default to 1.0.0 if left unspecified, names might default to
> lowercased classnames, @avalon.dependency mapped into
> @avalon.meta.dependency and @avalon.service mapped into
> @avalon.meta.service, resulting in a fully functional LCD.
LCD fails to deliver the aim of portable declarations.
If a component declares a lifecycle stage then that component should not
be deployable in Phoenix. To ensure this - the Phoenix meta generation
tool MUST recognize a lifecycle stage extension tag. Same story for
lifestyle - it MUST be recognized in order to ensure non-deployment.
LCD simply means potential runtime failure. This makes LCD unusable.
>
> == @avalon.meta.namespace ==
> class Enables client modification of the tag namespace.
<snip>
I aggree that this one can dissapear.
> == @avalon.meta.version ==
> class Identifies a class or interface are a Type or Service.
>
> <type><info><version>1.3.0<version></info></type>
>
> === comments ===
>
> - why is there a <version/> for classes?
It is the declaration of the implememtation version of the class. This
reflects the behavioural contract (as distinct from the interface
contract). A component with a major version incriment refects a
incompatible semantic change which may be independent of the interface
change. For example, semantics may be introduced on the interpritation
of a string argument. The interface reamins the same, but the sematics
of the implementation may have changed in an incompatible manner. This
information can be used by custom selectors and/or management tools.
>
> - can you depend on a version of a class? Why?
An ORB version 1.x is very different to version 2.x. The implementation
version 2.1 a lower level of functionality to 2.4. Yes - you can depend
on this sort of information because it reflects compliance with
implementation semantic constraints.
>
> - why is the standard '@version' tag not usable for this purpose?
The @version tag is typically used to reflect CVS versioning.
Overloading this with formal class implementation versioning would be a
bad thing to do.
>
> == @avalon.meta.attribute ==
> class A attribute associated with a containing type or service.
>
> <service>
> <attributes>
> <attribute name="description" value="an example"/>
> <attribute name="color" value="red"/>
> <attribute name="priority" value="normal"/>
> </attributes>
> </service>
>
> === comments ===
>
> Is it not better to simply make all unknown javadoc tags into an
> "attribute"? IE:
>
> /**
> * @my.tag jo!
> * @my.second.tag blah blah blah
> */
I don't like the idea of bundliung anything that is unknown (I can just
see lots of future problems, not to mention the fact that junk
information will end up on the screens of management tools).
These attributes are used to suppliement a component description with
information that will typically be specific to a container , component
or service. In the general case - attributes should be ignorable - but
there defintition as meta-info attributes should be explicit. This
simply means that if a named value pair is to be associated with a
component type - then there is a standard way to do it.
<snip-examples/>
I like the declaration approach of multi attributes ion a single
declaration. The current approach was largely driven by the assumption
that multiple line usage was not possible (thanks for the correction on
that one).
As far as the type and service instance meta-info declaration is
concerned this could be expressed as:
@avalon.info
somekey="some value"
anotherkey="another value"
>
> More in general, javadoc tags are attributes already, so why specify a
> special kind of "attribute" to mark an attribute as an attribute?
> Similarly, <attribute/> feels icky, since an xml attribute is defined as
>
> <element attributename="attributevalue"/>
Bacause explicit attribute declarations ensure the XML based meta-info
can be validated against a DTD. This means that we have to deal with
known attribute names and elements. The sort of attribute keys and
values we are dealing with here are unknown.
> == @avalon.meta.name ==
> class Declaration of a component type name.
>
> The name tag associates a name to a component type. The name tag is a
> required when generating a type descriptor.
>
> === Comments ===
>
> That's a bit vague; the type DTD got me
>
> <!--
> The component element describes the component, it defines:
>
> name the human readable name of component type. Must be a string
> containing alphanumeric characters, '.', '_' and starting
> with a letter.
> ... -->
>
> I think "human-readable" implies a free form string. IIUC, name is
> used to hold a reference to a type, component, service, in map
> structures (ie HashMaps, service managers, etc), but that only
> requires uniqueness, not anything else.
>
> If it is _not_ used for this, then what is it used for at all?
Within Merlin it provides two functions
(a) the association of a name to the type (e.g. "keystore") that
can be viewed by a management tool
(b) it establishes the default name for an implict deployment
instance
Both name and version tags could be combined under a @avalon.component tag:
@avalon.component name="keystore" version="2.7"
> == @avalon.meta.lifestyle ==
> class Declaration of the lifestyle policy.
> === comments ===
>
> the above sample provides ambiguity (example:
Agreed. This has already come up on the users list. The lifestyle
attribute will be folded into a sub-element of the <info> block in the
near futue.
>
> == @avalon.meta.service ==
> class Service export declaration from a type.
>
> This maps to '@avalon.service' from AMTAGS directly:
Yep.
>
>
> * @avalon.meta.service type="net.osm.vault.Vault;
> * @avalon.meta.service type="net.osm.vault.KeystoreHandler:2.1.1;
>
> note the typo, this should be:
>
> * @avalon.meta.service type="net.osm.vault.Vault"
> * @avalon.meta.service type="net.osm.vault.KeystoreHandler:2.1.1"
Brain is on slow - what type?
>
>
> === comments ===
>
> Of course, the ":2.1.1" is there for a reason. The example implies
> this is not a freeform string, but rather a specific version of a
> service may be exported by providing ":2.1.1". Especially since no
> prefix results in auto-addition of ":1.0.0". This seems like a bad
> idea. These things are seperate and introducing another kind of
> construct (the ':' within a value to seperate values) seems much worse
> than
>
> * @avalon.meta.service type="net.osm.vault.Vault" version="1.1.1"
Moving to an explicit version would be implicit with migration to a
complete "common model".
> <type>
> <info>
> <version>5.1.0</version>
> <name>vault</name>
> </info>
> <services>
> <service type="net.osm.vault.Vault"
> version="1.1.1"/>
> </services>
> </type>
>
> Better stil, since the code will do
>
> class MyVault implements net.osm.vault.Vault
>
> it is probably a better idea to have the tool determine what version
> of Vault is exported by taking a look at what version of Vault is on
> the compile path. That requires some work of course.
More than a little work when you take into consideration the possibility
of multiple service defitions of the same type but with different
versions. This possibility exists as soon as you have stacked
repositories mapped to stacked classloaders.
> == @avalon.meta.stage ==
> class Lifecycle stage dependency declaration.
>
> === comments ===
>
> this is container-specific. Or perhaps excalibur-lifecycle-specific.
It is not container specific.
It is a concept used in the majority of Avalon containers (Fortress and
Merlin) and needs to be recognized by Phoenix because Phoenix needs to
throw out componets that require extension stages. This is one of those
"crunch" issues - if we don't recognize extensions we cannot deliver
portable defintions.
> == @avalon.meta.extension ==
> class Lifecycle stage handling capability declaration.
>
> === comments ===
>
> this is container-specific. Or perhaps excalibur-lifecycle-specific.
Unlike the stage declaration, this can be container specific because it
is the defintion of a components ability to provide extension handling.
>
> == @avalon.meta.logger ==
> enableLogging() Logging channel name declaration.
>
> /**
> * Supply of a logging channel to the component.
> * @param logger the logging channel
> * @avalon.meta.logger name="system"
> */
> public void enableLogging( Logger logger )
> {
> super.enableLogging( logger );
> m_system = logger.getChildLogger( "system" );
> }
>
> <type>
> <info>
> <version>2.4.0</version>
> <name>component</name>
> </info>
> <loggers>
> <logger name="system"/>
> </loggers>
> </type>
>
> === comments ===
>
> by contract, logger.getChildLogger() should work, even without such a
> declaration. So why is the declaration there at all?
The declaration is there so that assemblers can do useful things. You
want to declare (via a directive) a logging target for a nameed
channel. The only way you can do this from a management tool is to pull
in the channels declarations that a type declares. For example, you may
have a channel that you want to encrypt. How does the management tool
get a refewrence to the channel name in order to build the directive?
> In particular, what happens if you change to <logger name="blah"/>?
> Nothing, right?
Wrong.
What changes is the information that is presented to a management tool
and the potential for assembly stage customization and control (i.e.
what changes is the usability and manaagability of the component system).
>
>
>
> == @avalon.meta.context ==
> contextualize() Declaration of a specialized context class.
>
> /**
> * @avalon.meta.context type="net.osm.CustomContext"
> */
> public void contextualize( Context context )
> throws ContextException
> {
> CustomContext custom = (CustomContext) context;
> ...
> }
>
> === commments ===
>
> that should be discouraged! The contextualize() contract is that a
> component can expect to receive a Context, nothing /more/, nothing
> /less/. I think BlockContext shows how problematic the above is.
Avalon contextualize implies this constraint. In practive many
containers define extended context interfaces (Phoenix, Plexus, ...).
In addition users prefer to use things like File file =
context.getWorkingDirectory() as opposed to File file = (File)
context.get( SOME_KEY ). Thing is that this is required if you going to
run a Phoneix component that assumes BlockContext. The important point
here is that Avalon containers need to recognize this casting criteria
and reject the component if they cannot support it.
I.e. this is one of those CRUNCH issues.
>
> == @avalon.meta.entry ==
> contextualize() Context entry declaration.
>
> === comments ===
>
> thought for a bit how this might be combined with
> @avalon.meta.dependency. Probably not a good idea.
This is also one of those declarations that must be recognized.
Optional entries can be ignored by containers, non-option cannot be
ignored.
> == @avalon.meta.dependency ==
> service() Service type dependency declaration.
>
> === comments ===
>
> maps to '@avalon.dependency' in AMTAGS.
Yep.
> == More on versioning ==
>
> Lots of unanswered questions.
>
> - do you really need this granular versioning?
Yes.
> Isn't versioning per deployable unit enough?
No. Different granularity.
>
>
> - when is a service backwards compatible?
Backward compatibility is undefined at this time (i.e. versions are
managed at absolutes). Looking forward, backward compatability semantics
would require more work on things like the framework Version class.
> How do you specify a version range?
Version ranges are not included.
> - how are versions actually used in container space? What can you
> expect to happen when you declare a version?
Components in a hierachy can provide different versions of the same
interface. When your mapping a provider to a consumer component you
basically search up the tree for a component exporting a matching
service (where matching means equivalent interface classname and
equivalent version). As mentioned above - this matching algorith is
currtently absolute but this is isolated in the equality test for a
service reference (allowing more general version semantics in the future).
> - how "optional" can version support be in a container?
A container can ignore this information and depend on "hope". The level
of confidence you can assign to "hope" semantics is typically a
container implemetation issue. Containers that use this information can
provide assured solutions.
>
> == summary ==
>
> use of '@avalon.meta' is a bad idea. s/@avalon.meta/@merlin/ would be
> nice.
>
> My biggest issue is with versioning. Either go all the way and declare
> (for example) that the arguments to some of the tags are urns in the
> avalon namespace (and declare the format for urns in that namespace),
> or be consistent in application of a pattern.
>
> Also, I'm sceptical as to the need of this granular kind of
> versioning, especially with regard to implementations.
>
> === existing merlin tags ===
>
> @avalon.meta.namespace should just dissapear
+1
>
> @avalon.meta.version should just use '@version', if
> needed at all
-1 mixes different concerns
>
> @avalon.meta.attribute should just dissapear; this stuff
> is attributes already. If there's really a need for avalon container
> support, just implement a generic algorithm that stores all unknown
> attributes (or even all attributes), rather than invent a new
> mechanism
-1 should not dissapear - tag spec and structure can be improved
> @avalon.meta.name needs more specification as to intended
> usage, and perhaps should allow free-form strings
+1 on more specification
-1 on free-form strings
>
>
> @avalon.meta.lifestyle no comment
>
> @avalon.meta.service <-> AMTAGS @avalon.service; concerns
> about versioning setup
>
> @avalon.meta.stage tied to excalibur-lifecycle package
>
> @avalon.meta.extension tied to excalibur-lifecycle package
>
> @avalon.meta.logger should just dissapear
-1
Put on a suite, re-read email, and think about management implications.
>
> @avalon.meta.context has a use case because there exist
> components that depend on specific context implementations or
> extensions (ie BlockContext), but should be discouraged
If you have a complete interoperable solution - then there is no need to
discourage the practice. It is possible to provide solutions to both
context casting and context semantic additions (and both are required if
you want to provide complete Phoenix compatibility). All we should be
addressing here is "what information at the tag level is needed to
completely declare the criteria of a component type". Using Phoenix as
a case study this means (a) context casting assumptions, (b) context
enty assumptions, (c) context behavioural assumptions. Our tag model
for context has to address all three.
>
> @avalon.meta.entry no comment
>
> @avalon.meta.dependency <-> AMTAGS @avalon.service; concerns
> about versioning setup
>
>
> == conclusion ==
>
> The tags currently in use by merlin are not ready for generalization
> into a "full suite of tags". I think some things do not make sense,
> and in other places contracts are underspecified.
I think you have made some good suggestions for improving the Merlin tag
suite. I also think you still missing the point about what is really
required for a generic and complete specification that would enable
"assured component portability" and "assured component integrity". What
I'm talking about is recognizing that a bunch of stuff MUST BE
RECOGNIZED irrespective of container support. Until we reach a general
acceptance of this truth a common tag model will be of little value.
Cheers, Steve.
--
Stephen J. McConnell
mailto:mcconnell@apache.org
http://www.osm.net
Sent via James running under Merlin as an NT service.
http://avalon.apache.org/sandbox/merlin
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org