Peter,
I'm happy with the interfaces themselves. To all intents and purposes they hae been stable for years. Docs being incomplete is where I'll meet you on definition.We do have a definition :-http://jakarta.apache.org/avalon/framework/reference-the-lifecycle.html
I do accept that docs could be improved.
The definition is incomplete. That's not a big deal - it's a typical situation for a framework in development. I'm just saying that it needs a little work. And that the work would be best served if contributors to a number of containers chimed in and the points of commonality are properly identified.
Only if you are interested in component/container interoperability. If you were a commercial company that had chosen one container over another, strongy typed context is an advantage. If you change your mind on container, then refactoring from FooContext to BarContext is cheap. If you are a generic provider of comps then you'll err towards weak typing I guess. * More later.This is because Context is a base for ServletContext (the A-F designnot
yet written), MailetContext, BeanContext (written for EOB),BlahContext.
Some of them may offer a 'get root dir' feature, some may not. Do weMerlinApps
encode all permutations for Servlets, Mailets, Beans, Blocks,
in the same file? I think not. Anyone can code a component that cantwo
implements one or all of the A-F interfaces, and is extended by say
subclasses (also comps). e.g..Net
abstract class FooDaemon implements Startable, Runnable,
Contextualizable {
Thread thread;
File rootDir;
// from A-F Startable
void start() {
thread = new Thread(this);
thread.start();
}
// from A-F Startable
void stop() {
thread.stop();
}
}
class PhoenixFooDaemon extends FooDaemon {
// from A-F Contextualizable
void contextualize(Context context) {
rootDir = ((BlockContext) context).getRootDir();
}
}
class EOBFooDaemon extends FooDaemon {
// from A-F Contextualizable
void contextualize(Context context) {
rootDir = ((BeanContext) context).getRootDir();
}
}
With the above design, you interoperability with Phoenix and EOB (a
Remoting inspired app server I work on). Replace the word 'EOB' withand
JAMES (one day?), or Merlin, or Catalina's internals (one day?).
Containers are all different. They use differnet cop-lacing, config
context.the
The point is that Context is deliberately vague. Either we define a
massive hierarchy of Context interfaces in the A-F package (and curse
ourselves at our liesure over the years), or we leave the context to
container in question. Phoenix and Merlin are just two containers.
They are not going to be the last 'coarse grained application server'
containers.
I don't really agree with the above. :) Which, of course, is why I asked for discussion on the topic. The subclassing you suggest is interesting, but i) making it necessary for the components to be aware of specific context implementations and ii) placing those implementations in container space as opposed to common space seem to kill the proposal for me as an Avalon consumer.
Context, as currently designed, is useless. It requires AvalonI'm still -1 on the "massive hierarchy of Context interfaces", however you are right to point out that as a user, you are right to rase you concerns. You inport is more relevant that <apologies> partisan fighters on from this list.
components that wish to use elements out of the context to be aware of
container level details that are not specified in the framework. For
clarity on this issue, see the org.apache.james.context package in the
James source code. But the long and the short of it is that the
vagueness of the Context contract makes it impossible for a consumer to
write a container-independent component that uses the Context.
I think your suggestion of a "massive hierarchy of Context interfaces",
despite the clear negative connotation, is the most sensible suggestion
in the above.
There are specialist containers like James which would probably go the strongly typed route for it's hosted components (Mailets, ForwardingMailets, ConsumingMailets, FilteringMailets, DivertingMailets etc.). A rude assumption that you folks rejoin the A-F believer's camp ;-)
Maybe for general containers we do have some extended Context defined in the A-F package (I will not vote in favor of some other package Meta/Info/Uber/X for standard inclusion for A-F contact). What I am floating for idea is
public interface Context {
Object get( Object key ) throws ContextException;
}
public interface ContainerInstructableContext {
void requestShutdown();
}
public interface ClassLoaderQueryingContext {
ClassLoader getClassLoader(String name);
}
These are a single dimensional list of interfaces that could be usable to a number of containers (general or bespoke). There is deliberatedly no inheritance here. The hierarchy would be a fallasy. Container writers choose which of the interfaces they support. Specialist container writers (say JAMES) support a couple of these, but largely push ahead with their own context, which is *definatly* not bound into the A-F interface structure.
e.g. for JAMES (and in James's CVS)
public interface BaseMailetContext extends Context {
Blah getSomeCommonJamesThing();
}
public interface ForwardingMailetContext extends BaseMailetContext {
void forward(MailItem mailItem, String mailRecipient);
}
public interface ComsumingMailetContext extends BaseMailetContext {
void consume(MailItem mailItem);
}
It does not address a declaration mechanism. The container could simply catch NoClassDefFound or some simple (please god) mechanism could be found. Given that is meta info, I am going to push for Container writer's choosing their own lacing mechanism.
Similarly Jesktop (a comtainer I need to update soon) could have ...
public interface DesktopContext extends Context {
void someDesktopInteraction(String blah);
}
... but that clearly has no place in the A-F set.
The point is that the set is small. More later!
Each of the Context related interfaces would be p
art of
the definition of a contract that would be part of the framework. They
could be simple marker interfaces with associated key/object pairs
guaranteed by the contract, or they could have substantial syntactic
sugar (a la Phoenix's BlockContext class). By using lightweight,
tightly defined interfaces that basically provide keys for the get() or
provide syntactic sugar that wraps the get, we ensure that we don't
overly restrict containers. Context doesn't care how the container
provides the object in the contract, only that it provides it.
This approach would allow containers to declare simply in their
documentation what context contracts they support. Component developers
could declare what context contracts they require. Component deployers
would know immediately whether a container was sufficient to run their
component.
Covered I think.
For example, James could put something in the docs that states "Any
Avalon container that supports the File context contract is sufficient
to run the James server.". If there were a container designed to run on
an embedded platform that didn't expose a file system, it would be
immediately obvious from the docs that James wouldn't function.
Covered, apart from the declaration.
This approach would maintain the flexibility that people clearly want
(i.e. Noel's suggestion of J2ME support, 31 containers of different
flavors) while allowing component developer/deployers to have a more
efficient approach to application deployment than "try it and see".
Moreover, nothing in the above prevents container developers from
rolling out their own "custom" context contracts.
Agree.
It's just that any
component that uses such a contract will be tied to that container and
that container alone. That's ok, because the dependencies will be clear
to the component developers and deployers. As container/framework
versions iterate, context interfaces/contracts that are seen as
generally useful could be moved into the framework.
Agree, but without the hierarchy (a fallacy).
This is a standard
paradigm of framework and API development.
This discussion is a standard extensibility/usability trade-off. By
making Context essentially infinitely extensible (it's nothing more than
a glorified HashMap) it's been made totally useless. This can be
resolved by giving the component deployers narrow contracts defined in
the common code base (i.e. framework) that they can check and validate
their components against. How we do this is really the question.
Apart from anything else, it was voted on before that Merlin includethe
tiny Phoenix-Client jar in it's client API classloader and honorsAnd that's exactly the problem we're trying to resolve. This approach
BlockContext as is (if it wanted to be compatible with Phoenix).
makes Phoenix first among all containers. I like Phoenix, and I have
suppored using Phoenix for James' standard distribution, but you can't
simultaneously argue that all containers are equal, while stating that
some containers are more equal than others. Last I checked, Animal Farm
wasn't on any university's computer science reading list. :)
A good point. We'll disagree though
Yup.Phoenix is a very good container. I'm impressed by Phoenix, but this sort of single container-centric view is detrimental to the multi-container world view you seem to want to espouse. Personally, I don't see how you can resolve the two.
ofI'd argue that a standard, minimal set of keys/object should be part
uselessthe Context contract. Otherwise the Context interface is fairly
customas part of framework since every container would provide a purely
That would be fine. See my comments above.set of keys/values. Thus any code written that implementedYou can go for that if you like. Code something that is adaptive and
Contextualizable would be implicitly container dependent.
used the primitive get() mechanism.
Maybe we should have a single additional context method called
getContainer(). It returns "Phoenix 4.0.2" where that were true. Or
maybe a method called isCompatibleWith("Phoenix 4.x")
Ugh. Typing containers via strings? Requiring components to be knowledgeable of container names which aren't defined in the framework? Double ugh.
I'm perhaps eluding to a more elegent discovery mechanism. Perhaps wrong.
True, but as third and fourth coarse containers enter the fray, they will seek to emulate first and second. Perhaps wrong, I accept.We (specifically some of the Avalon consumers) keep trying to make clear that the line needs to be drawn between what is common and what is not. General components should only need to be aware of the details of the commons (framework, Apache commons, Jakarta commons). They shouldn't need to know anything about a particular container - not even its name.
- Paul
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
