Leo Simons wrote:
On Sun, 2002-11-24 at 21:53, Nicola Ken Barozzi wrote:Technical point - you cannot provide an instance of java.io.File as a service - instead you need to wrap this in a FileService and then provide an access method. After you have done that (taking into account the pros and cons) then, yes, you can consider Service/Componentable as viable options to Contextualizable.
Stephen McConnell wrote:(aside: just about any context material can be put in a service instead
Leo Sutic wrote:
Fourth, you do not provide any reason at all for a context. Reading yourYour making the assumption that a container can only provide canstant -values in context. I don't agree with assumption. Take for example a container that is providing an activation timestamp, the key-chain of the invoking user, and a classloader. These values will typically be different in every application of contexualize. These values canot be expressed in a configuration, or parameters, or under the Serviceable or Composable interfaces.
mail, my conclusion would be to dump the Context completely. I think it
has been shown that everything can be realized as a service, and then
we would not be limited to constant-value lookup (which is more suitable
for a Configuration anyway).
with enough effort:
blah = context.get("blah");
VS
blahservice = service.get("blahservice");
context = blahservice.getContext();
blah = context.get("blah");
so that last sentence is not true.
It is also not the issue ;)
Abstract
--------
Then please comment on the below code.separation of concerns. The rest of this rather lengthy e-mail tries to
What's the real difference?
explain by example. The point I make at the end of the e-mail is that
regardless of the real differences, it is best if only one of the
patterns is followed.
The easy answer
---------------
How can a coder easily decide what to use?
He looks at what the container(s) he wants to use provide him with. If the container doesn't provide him with the information he needs, he has to add it himself in some form. The easiest way to add this functionality is to get a TimestampService from a central repository. A container developer has to choose between providing "very clean and lean" and providing "the kitchen sink". Avalon has to concern itself with trying to make the job easy for the component developer, and to lesser extend the container developer.
+1, last sentence - yes, yes, yes, - yes ..!
Extended example
----------------
Let's abuse that timestamp example:
Timestamp appStarted = (Timestamp) context.get(
CommonContextKeys.STARTUP_TIMESTAMP );
Timestamp appRestarted = (Timestamp) context.get(
CommonContextKeys.RESTART_TIMESTAMP );
Timestamp componentStarted = (Timestamp) context.get(
CommonContextKeys.COMPONENT_RESTART_TIMESTAMP );
Timestamp componentRestarted = (Timestamp) context.get(
CommonContextKeys.COMPONENT_RESTART_TIMESTAMP );
this is all information that could be argued should come from the
container (if it is to be provided, that is, which is a different topic
altogether ;). The difference with
TimedContext context = (TimedContext)c;
Timestamp appStarted = context.getStartupTimestamp();
Timestamp appRestarted = (Timestamp) context.getRestartTimestamp();
Timestamp componentStarted = (Timestamp)
context.getComponentStartTimestamp();
Timestamp componentRestarted = (Timestamp)
context.getComponentRestartTimestamp();
is mostly syntax sugar. Now consider:
Timestamp currentTimeInBrazil = (Timestamp) context.get(
CommonContextKeys.CURRENT_TIME_IN_BRAZIL_IF_WE'RE_TRAVELING_AT_HALF_THE_SPEED_OF_LIGHT );
Eeeek!
Which is perfectly rationale ...or even: Timestamp currentTimeInBrazil = (Timestamp) context.getCurrentTimeInBrazilIfWereTravelingAtHalfTheSpeedOfLight(); which is clearly not good because one can certainly not expect a container (let alone all containers) to keep track of the current time in Brazil, let alone know about quamtum mechanics. _If_ there is a container which supports this kind of stuff, you can be rather sure it's the only one!
public CurrentTimeInBrazilIfWereTravellingAtHalfTheSpeedOfLightContainer
extends DefaultContainer
{
// - deploys components with light-speed context
// - approach seperates container side programming from
// component side programming
// - container specifics are isolated here
// - results in portable componets <----------
// - its easy to do within minimum code
}
Why mention this - bacuase it is import to understand that there are two side to component-oriented-development (a) the component, and (b) the container - and its really import to appreciate the potential of isolating these two concerns - because it enables the delivery of portable components, by leveraging a containment solution.
Specalizing a container does not mean lost of Avalon container - its about having a container side programming model that makes the above a drop-dead simple proposition.
Now the grey area:
Timestamp currentTime = (Timestamp) context.get(
CommonContextKeys.CURRENT_TIME );
Yep.
which is where things get hairy. This is of course mapped to System.getCurrentTime() (or whatever that is called), but to make the example valid assume that such a method does not exist and the container talks to the OS (or some time server) to figure this out. Would it be possible to extract out the code from the container that talks to the OS and make it into a service? Probably. You get: Timestamp appStarted = context.getStartupTimestamp(); Timestamp appRestarted = (Timestamp) context.getRestartTimestamp(); Timestamp componentStarted = (Timestamp) context.getComponentStartTimestamp(); Timestamp componentRestarted = (Timestamp) context.getComponentRestartTimestamp(); Would that be smart? That depends. Perhaps talking to the OS is something you want to enable the container to do but not hosted components (ie security). Should you then use some kind of security management kernel plug-in for this? Depends. Perhaps you know for certain that this is the only case where a component needs to talk to the underlying OS directly and you don't want all the security complexity and overhead. The long answer --------------- If your problems are simple enough it seems rather silly to bother with a framework at all (example: using phoenix to run a component that prints 'hello world' to the console); debating which approach is the best becomes real difficult. Separation of concerns is the hardest thing to do in software architecture. There's not always a definite answer. Thing is (important point!), from the "One Framework" point of view, the use of services vs the use of context means the common ground shared between containers can be smaller while having components that are still portable across containers.
Yep.
If you depend on a getBlahStuff() in a SpecificContainerContext, you
cannot move your component into a container that doesn't provide you
with getBlah() (usually you won't be able to move your component into a
container that doesn't provide you with a SpecificContainerContext).
If your component depends on a BlahStuff being available as a service
(where BlahStuff is provided by the SpecificContainer), you can use
BlahStuff inside AnotherContainer as long as it is possible to create a
BlahStuff service yourself that can run in AnotherContainer.
Yep
Real-life example
-----------------
As a concrete example, from the current BlockContext (inside phoenix
CVS):
/**
* Retrieve the MBeanServer for this application.
*
* NOTE: Unsure if this will ever be implemented
* may be retrievable via CM instead, or perhaps in
* a directory or whatever.
*/
//MBeanServer getMBeanServer();
Now, if phoenix where to indeed provide access to the MBeanServer (which
is at the core of the JMX management extensions) this way, and you have
a component that depends on that, a requirement for moving that
component to Merlin (or EOB, plexus, or "Avalon Container for J2ME"....)
is that Merlin also exposes an MBeanServer in this way (atm, Merlin has
no clue about what an MBeanServer is).
And should not know. (its not part of the core framework contract)
OTOH, if a component gets at that MBeanServer through a ServiceManager,
you can move that component to Merlin without problems, as long as you
are able to find or write an MBeanServer that can also run in Merlin.
+1
Even when component portability is not a problem (there's only "TheOff topic but you've given me some great ideas about the sort of thing we could talk about in the PMC.
Official Avalon Container" and no-one is allowed to make another one or
they'll be visited by the feds), there's a compatibility problem when
"The Official Avalon Container" wants to switch from providing an
MBeanServer to providing a SoapServer, or wants to switch to a new
version of the JMX spec.
* case assesment of SOC infringments
* policy to apply on IOC violations - community service
or something stronger ?
;-)
On a more serious note - I hope we don't arrive at a scenario where the "Official Avalon Container" provides any services beyond delivering completely and succinctly the "Avalon Framework Component Contract".
Of course, if you make things dynamic enough all these problems go away.
Doing lots of dynamic proxying would certainly get us somewhere (cost:
the container code becomes more and more complex); using a weakly typed
language might solve this as well.
Wrapping up
-----------
Anyway, see the differences now?
Regardless of what we figure is the best way to all this in the end, it
is beneficial to both component developers and container developers if
the way to handle this stuff becomes a widely applied pattern if
possible. If both phoenix, merlin, EOB and James provide a
CURRENT_TIME_IN_BRAZIL_IF_WE'RE_TRAVELING_AT_HALF_THE_SPEED_OF_LIGHT,
but the code you need to get at it is different in every one of them,
that's no good. That is why it is worth spending countless hours
discussing all this :D
long live the lengthy e-mail, g'night,
One more note for the dedicate that are following this thread
Context - ADVANTAGES
* your providing state, not service and that keeps component
implememntation simpler and more reusable bacause it does
not need to know about service semantics
* is more more efficient because there is no assemably, lifestyle
or lifecycle overhead
Context - DISAVANTAGES
* no structure for automated logging assignment
* no framework for cofiguration on context values
* no framework for paramaterization of context vlaues
* no framework for assembly of context values
* no lifestyle semantics
* no notion of decommissioning of context entries
And the inverse:
Service - ADVANTAGES
* container handles component provider assembly automatically
* container handles lifestyle management for you
* container handles lifecycle processing for you
* container handles service decommissioning
* container can provide seperation between implemetation and
service automatically
Service - DISAVANTAGES
* if its data you after then more lines of code are needed
* component implememtation becomes tightly coupled
to the service interface reducing potential reuse
and potential to use alternative service solutions
* less efficient due to assembly, lifestyle and lifecycle
overhead
Cheers, Steve.
- Leo
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
-- Stephen J. McConnell OSM SARL digital products for a global economy mailto:[EMAIL PROTECTED] http://www.osm.net -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
