avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Leo Simons <leosim...@apache.org>
Subject [RT] defining compatibility
Date Thu, 19 Feb 2004 17:06:40 GMT
Hi gang,

= preface =

[RT] are Ramdom Thoughts.  They are tradition in the Avalon community.
RTs are basically long and thought-provocing mails with new project
propositions, that are discussed and scrutinized at length.  One
distinguishing characteristic about RTs is the complete and utter lack
of consistency with respect to quality: some are pure crap, others are
pure genius.  Even the original author of a RT is not sure which
category any given posting falls into at the time it is issued.  This
posting is no exception. [*]

I've been sitting on this one a while (I typed the below a week or two 
ago I think). Let's open up a big can of worms :D

= Introduction =

here's a rather 'big' question: when can we say that a container is
compatible with avalon-framework?

I want the answer, because I have a project for which I want to claim it
is compatible. Actually, I've wanted an answer for a long time, but
there is now sufficient itch to spend time on it.

I have spent a few weeks researching all of this. This e-mail contains
many assorted thoughts on the subject. I'm sorry for its length. It is
probably best to discuss all the particular issues piece by piece, but I
felt I couldn't make most of my categorizations and choices clear
without resorting to the extensive use of examples. Please do snip all
specific issues on replies and talk about the general cases. When we
nail those down we can get to specifics.

= Defining the question =

For definition purposes, a container is that piece of software which
fulfills the container side of the avalon-framework
container<->component contract. "Something" which the user can configure
in "some" way to host any component that complies with the component
side of the avalon-framework container<->component contract.

A container is compatible with avalon-framework when it fully fulfills
the avalon-framework container<->component contract.

That much is clear to everyone (I think). But that's still pretty vague.
There's two subissues:

* how do we verify compatibility?
* what is the avalon-framework container<->component contract,

= Issue 1: how do we verify compatibility? =

Well, as far as java-level compatibility is concerned, I have an answer,
at least a "batteplan" [1]. You create some test components that log
whatever happens to them, specify that a container must load up these
components, then verify that the component log is in accordance with the
specification. So you test the container<->component contract by making
the component side of that contract verify that things happen as they

= Issue 2: what is the container<->component contract? =

This is the really big one. Let's split it.

== The obvious parts ==

Many things are obvious. Let's call these the "fully specified
contracts". A few examples are:

* if a component implements the LogEnabled interface, the container must
provide a logger to it in accordance with the LogEnabled contract;

* if a component implements the Loggable interface, the container must
provide a logger to it in accordance with the Loggable contract;

* if a component implements the Servicable interface, the container must
provide a service manager to it in accordance with the ServiceManager

=== What do we do? ===

There's not much to do. This stuff is already specified in

=== IMHO ===

Within the TCK setup I'm working on, these are easily tested.

== The somewhat less obvious parts ==

Then there are things that would probably be easily "fully specified",
but aren't at the moment. Let's call these the "underspecified
contracts". A few examples:

* if a component implements the LogEnabled interface and the Loggable
interface, the container must not load the component, but rather,
generate and report some sort of exception.

* if a component does not implement the Component interface, the
container must use some kind of technique to make sure the component is
still available through the ComponentManager provided to Composable
components (typically using some kind of proxying).

These are currently underspecified simply because we've never really
dealt very much with "formal compliance". We simply had container
implementations which did most of these the same way (though I can't
tell from memory what exactly all the containers do with the
LogEnabled/Loggable ambiguity at the moment, for example), to the extend
that 99% of users would never encounter them, or just accept their
behaviour when they found them and work around the issue.

=== what do we do? ===

within the TCK setup I'm working on, these are usually easily tested as
well, but it is not always clear to me what to test for. Do we want to
unambiguously specify these kinds of things? If we do, here's some
likely consequences:

* we will spend many hours in debate over some of these issues as they
   pop up;
* when any particular choice is made, it is likely to impact many
   existing applications as they will suddenly not be compliant;
* dated releases of containers developed internally to avalon will
   likely not be compliant with out own specifications anymore.

An alternative is to keep them vague. May sound like a bad idea, but
we've managed to do so for quite some time now.

=== IMHO ===

We should work on specifying these one by one.

== The contentious parts ==

Then there are some things that are more or less "fully specified", but
not supported in many container implementations. Making these part of
the compatibility stamp would actually render various containers
incompatible. The avalon development team has historically been in
disagreement over these. For want of a better term, let's call these
"malspecified contracts".

Specifically, ECM and Fortress support some parts of the
avalon-framework contract, that merlin and phoenix do not support.
Top-of-head, these are:

  * Selector semantics within provided ComponentManager and
  * ThreadSafe and SingleThreaded marker interfaces

These are also easily tested, but the question "are these a
requirement?" is much more difficult to answer. For example, it is not
particularly likely that merlin will provide support for these contracts
anytime soon, yet merlin will probably soon grow into the de facto
reference implementation for avalon. That would mean the reference
implementation is incompatible with the reference.

Yet there's a whole range of applications out there that absolutely
depend on selector semantics. The most visible one is cocoon. You can't
run cocoon on merlin because cocoon really needs Selector wiring.

=== what do we do? ===

It's a rather nasty issue. Furthermore, reaching consensus on it will
probably be rather painful. Judging from the past, it might even be
impossible. We can preserve the status quo, we can make all containers
support all of these, or we can reject some of it (with that, rejecting
some of our users).

=== IMHO ===

Selector semantics are and should remain part of the avalon-framework
contract, because it has been in the distro's and documentation for a
long time and there are a large number of componentns that use them.
OTOH, ThreadSafe and SingleThreaded should be "soft-deprecated" (ie we
put notices in the docs but no '@deprecated' tags), and compatibility
should mean that containers do not check for or depend on their usage.

== Extensions of the container<->component contract ==

And then there's a whole range of things that are a rather essential
part of working with any one of the current containers, but are not
really part of the avalon-framework contract at all. Let's call these
the "unspecified contracts". They're often specified, but not as part of
the avalon-framework contract. Some examples:

* ECM, Fortress and Merlin support different lifestyles for components,
like "singleton", "singlethreaded", and "transient". ECM, Fortress and
older versions of Merlin also support "pooled". Phoenix supports only
"singleton". There are some "hints" about lifestyle in the
avalon-framework interfaces (the aforementioned ThreadSafe and
SingleThreaded interfaces), but in general lifestyle is not part of the
avalon-framework contract.

* AIUI, merlin will not allow you to run a component for which you have
not fully specified (or at least specified you want the merlin defaults)
what you want to do...a component author or assembler must declare what
parts of the container<->component contract any particular component
will use, and if it violates those declarations merlin will complain.
This is quite different from (for example) ECM, which does not provide a
mechanism for declaring this kind of information. Fortress and Phoenix
are somewhat inbetween the two, but all of them use a different mechanism.

* phoenix supports "[]" and "{}" postfixes on the role provided to the
ServiceManager/ComponentManager lookup method, which, when used, will
return an array or list containing all of the

=== what do we do? ===

On the one hand is the option of making all of these things part of the
avalon-framework contract. On the other hand is the option of making
none of these things part of the avalon-framework contract. Then there's
options in between, like making them standard extensions.

The pros and cons of each of these choices vary for each of these issues
vary per issue. For example, making merlin-style contract declaration
into an extension doesn't make a component less portable: if you include
the definitions, the component can run in all containers. But with the
"[]" semantics, if you have a component that uses it, that component is
from there on just about nonportable (unless you go out of your way)
(which is an argument for either making it official or rejecting it

Figuring these choices out is also going to be difficult. For example,
active users and proponents of a particular feature/choice will likely
want it to be standard, whereas container developers who don't want to
support the feature will not want it to be standard.

With java, these things are easy: sun/the jcp lays down absolute rules.
For us, we probably won't reach consensus without spending *much*
energy, and that's something we (I) don't like.

=== IMHO ===

* we should reject "[]" and "{}" semantics and any other semantics or
conventions like that (URIs in Context, etc);

* make support for lifestyle semantics part of the core contracts
insofar as that we standardize them and require that a container specify
(in its end user documentation) which ones it supports. Additionally,
they should be part of the TCK and the TCK should inform anyone that
runs it of the semantics a container supports;

* all of the other things I mention here (well, that I snipped for
brevity but that fit the category) should be seen as "standard
extensions", just like, for example JDBC is/was for the jdk. When
something like them is in use, and there is a "solid" specification,
they should follow whatever the stable release of merlin does. This
places a heavy responsibility on merlin. With the example of packaging
standards, it means that fortress and ecm are compatible (it doesn't
work with any archive format or does any kind of classloader control),
merlin is compatible (by definition) and phoenix is incompatible
(merlin's block format is different from the phoenix bar and sar formats).

== The user<->container contract ==

And then there's things like SAR archives, BAR archives, other packaging
formats (like standard places for storing metadata) dynamic blocks,
classloader management. It might be best for some users if some of that
were part of the core contracts. I don't think so, and I don't think its
a realistically attainable goal for the near future, but I thought I'd
mention it.

=== what do we do? ===

Agree that classloader management, archiving, service discovery,
security, all of these things are not part of the avalon-framework
contract but are additional contracts in a different problem domain.
While they're neccessary, and probably deserve specifications and TCKs
of their own, they have nothing to do with "avalon-framework compatible".

=== IMHO ===

* we should strive to define these things as standard extensions as
well, but be very clear that they are totally seperate from
avalon-framework and the container-component contract.

= So, what do we do? =

Here's the question again: when can we say that a container is
compatible with avalon-framework?

I provided some examples of different aspects of that question, some 
examples, and some opinions. It should be clear from the above that this 
is a complex topic. Here's the current answer to this question: we don't 
have an answer.

Without jumping into several-week-long discussion about each and every 
issue as it comes by according to our interests, let us think for a 
little about ways to formulate an answer together.

* We could say that compatibility is defined by the the least common
denominator of the current ecm/fortress/phoenix/merlin featureset. That
LCD is definable, testable, and hence not subject to much debate (if
there's debate, you can write a test to show compatibility or
incompatibility). It rules out any lifestyle but singleton, marker
interfaces, any combination of Loggable/LogEnabled or
Composable/Servicable, Executable, Re***, making avalon-meta part of the
avalon-framework contract, and many other things.

* Similarly, but with just current fortress/merlin as the LCD. This is
the "drop-a-lot-of-legacy" option. This would allow for lifestyles but
still rule out everything else.

* We could say that compatibility is defined by the ability to host and
run all applications that merlin can run. This in effect means that the
only compatible container is merlin, and everything else is incompatible.

* We could say that only the established and fully specified contracts
define compatibility. This means there will be components (for example,
those dependent on "[]" semantics or that will only run in a pooled
environment) that will be compatible that are impossible to run inside a
compatible container without (extensive) modification of the sources.

* We could just follow the "IMHO" bits and let me built the TCK on my
own and let that define compatible :D.

* We could categorize the compatibility issues along lines similar to
what I did above, discuss per-category, and make a choice per category.
This will likely leave some people unhappy with the result (I expect at
least myself :D), but its a workable way for moving forward.

* We could discuss each and every issue seperately. This will likely
take many months (after all, it has already taken some months in some
cases). This is an option that's not really a "we" as I will probably
run out of steam and drop the whole effort.

== IMHO ==

I don't know yet. I wanna hear other people's thoughts first.

= Battleplan =

What I would like to do is something like this:

1) brainstorm about all this together (throw out all those [RT]s :D) for
a week or two.
2) take some time to digest those braindumps.
3) do a summary of the important things in those braindumps, focussing
on finding what we already agree upon.
4) draft a proposal outline a procedure, decision process, and roadmap
for tackling the issues.
5) discuss, refine, then perhaps even vote on that proposal.
6) work step-by-step according to what's in the proposal (can't of
course, be more specific yet, but it'd better involve baby steps and use
of Jira :D).

= References =

[*] Preface courtesy of Sam Ruby :D


- Leo Simons

Weblog              -- http://leosimons.com/
IoC Component Glue  -- http://jicarilla.org/
Articles & Opinions -- http://articles.leosimons.com/
"We started off trying to set up a small anarchist community, but
  people wouldn't obey the rules."
                                                         -- Alan Bennett

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

View raw message