Jakob Praher wrote:
hi Stephen,
Am Don, 2003-03-13 um 14.20 schrieb Stephen McConnell:
Jakob Praher wrote:
I personally don't see this as a problem. The lifecycleWhat it lacks is the interception of calls from the client to the component, since, once the reference is out of the container, the container can't control the use (except in an micro kernel design, but that is suboptimial here).
interface deal with the defintion of the contract for an extension
implementation under the creation and access phases. The subject
of both of these phases is a component implementation and the
relationship between the container and extensions introduced into
the containement environment.
Things like interception of methodInteresting - I wanted to use something like that in my last project.
invocations is a seperate subject. For example, I use the
extensions to implement aspects of a system that are related to
deployment - I use interceptors for things like principal identity
propergation and establishment. The issues dealt with are quite
different.
What are you using - javaassist or bcel or sth else?
I'm using the IIOP interceptor architecture (CORBA etc.). In this particular case the issues of transaction identifiers, pricipals identities etc. are all handled before the invocation is hitting the service. The implementations of these interceptors leverage the Merlin framework in terms of interceptor establishment and dependency management.
But seeing it as a black box, from a clients perspective, I mean from th
e service consumer, that takes a component from the container and uses
it, it does not matter where the added service is added, for instance
transaction service - a client takes a component from the server and
wants transaction support, but for transaction boundaries access/release
boundaries are probably to coarse grained - how are you seeing it?
I think it's all about adding services to components.
I agree (its a black-box as far as the client is concerned). The trick is to handle this is a manner that is easiy understood and manageable in an environment of complex components. I do not believe that it is benefitial to take a "intercepts-equals-total-solution" approach (too much experience with interceptors to signup to that idea).
I think its more that just adding service to component. The container is responsible for the establishment of the component - and using things like proxies, it possible to modify the behaviour on an invocation. The questions concern the structure for declaring extensions to invocation semantics to a container - and doing that in a manner that is consitent across containers.
by orthogonal you think it is independent of - or?So the notion of a call interceptor get's introduced, the client get's aYes - possible (but in my opinion its orthoginal to the container
proxy back that intercepts the method call and does some extra magic.
extension architecture).
I mean that the notion of introducing customization of the behaviour of a container is common to both the questions of lifecycle phase estansion and invocation interception policy extension. However, the two concerns are very different in terms of the entry-point and time of existance. Lifecycle extensions exist during deployment, decommissioning and requersts for instance creation and destruction. The handling of interceptor policies is also an extension but it needs to be differentiated from lifecycle extension. So - by orthogonal - I mean that both problems share comonality at some point - but they both deal with seperate problems.
I'm still wondering about this. Guess I need to talk some more to Leo.To support proxies, as Leo pointed out, one could change the interface from
void created( Object object, Context context )
to Object created( Object object, Context context )
Suffice to say that I'm not convinced of the need for proxies during the
container side management phases. I have the impression that there is
mixup of concerns - lifecycle extensions are dealing with extension to
the deployment lifecycle which is a container concern unrelated to
extensions dealing with an invocation against a service.
Thinking about lifecycle I guess you are right - lifecycle means the lifespan of the object, which has not much to do with intercepting method calls, but one of the point is that the proxies must get introduced somewhere, since for interceptors to work the client should never receive a non proxy, so implementing this as special lifecycle extension would be convinient, since adding a proxy layer after object is created and *before* it is returned to the caller is afait a good place do it - where would you put it?
Thsi is somewhat container specific. In the Merlin container - the Appliance is the source of a service. It uses a bunch of internal managers to establish the component (or non-component) representing the service instance. When you make a lookup invocation on the ServiceManager - the ServiceManager implementation is simply invoking resolve on the appliance and returning the result to the client. The appliance has access to the object providing the service and all of its associated meta information and meta data. If meta data were to include interception policy declarations. the appliace can use this information to establish an invocation handler (proxy).
Honestly I don't know what the Fortress implementation approach is tobut what I am missing here is how to state which kind of aspect the object supports, for isntance, take the example of a componetn configuration with a "standardized" transaction support:
<component class="..." role="..." >
<ts:transaction-supported>auto</ts:transaction-supprted>
</component>
if you change the Method and add a configuration instance, or something like that, it would be much more interesting:
Object created( Obejct object, Context context, Configuration config ) ;
so you can transparently use a proxy to implement the invocation handler and *know* which kind of transaction logic should be used. (naive question: is this the kind of transaction demarcation support Peter asked?)
configuration of a extension handler - however, I can explain why this
is not needed within Merlin. In the Merlin environment an extension
handler is a component and as such, it configured during its deployment.
Any supplementary information can be supplied to the handler using the
existing signature via the context argument.
I have worked much, albeit with the excalibur impl, yet, and must
confess I haven't had the time to look into the details of merlin, I am
looking forward to get my hands on that beast - so I used the
configuration metaphor from excalibur here. Your description of Merlin sounds interesting - is this the direciton
which Avalon5 is taking?
Merlin makes extensive use of meta info and meta data. Certainly a community based evolution of a common Avalon meta model is on the roadmap. Once you establish that you eliminate a broad spectrum of incompatibility issues. For example, Merlin provides support for both the Phoenix and Meta packages in terms of meta model - this is why Merlin can run Phoenix components. With the establishment of a common meta model the container becomes academic - or more correctly - you select a container based on requires such as the ability to embed, functionality, utility, scalability, etc. It this the direction that Avalon is going ?
Yes.
as you could write a custom Creator class that calls on that component,Take a couple of example.I hope I have explained my ideas understandable, and bear with me since I am currently trying to get a handle on all of the AOP, Call interception things. As Leo pointed out the implementation of AOP in Java using bytecode transformation, custom proxies and the like is relatively easy and well documented, but for me it is sometimes hard to transform the topic to practical use, so any discussion is appreciated.
Let's imagine I want to introduce a different initialize signature into my component. Perhaps it takes a ServletConfig as an argument and throws a ServletException. This is perfect case for use of the lifecycle extensions package. In this scenario that handler could be constructing the config instance - perhaps based on service that the handler has acquired from its own dependencies. The handler simply builds the config argument and applies this to the supplied component. No need for proxies - good isolation of the extension from the container - and clear separation of container / component concerns between the extension handler and the target component.
in the create method,
class MyCreator implements Creator {
ServletConfig servletConfig = ?;
public void created( Object object, Context context )
throws Exception {
((Foo )object).specialConfig( servletConfig ) ;
}
...
}
is this right?
Yes.
* where would you declare this lifecycle extensions then? (in the case of merlin, for instance ? )
There are two parts - the component and the handler. The component declares the requirement for lifecycle stage interface support as follows:
<type>
<!-- custom meta attributes go here -->
<!-- logging, context and service depedencies go here -->
<!-- services that the implementation provides go here -->
<!-- lifecycle stage depedencies go here -->
<stages>
<stage type="org.apache.avalon.playground.Exploitable" />
<stage type="org.apache.avalon.playground.Demonstratable"/>
</stages>
</type>The above XML is contained in a file name <classname>.xinfo. It is the decklaration by a component implementation of its requirements from a container. In the case of lifecycle depedencies, this includes the declaration of the interface that it implements that should be considered as a deployment phase lifecycle stage. The order of stage declarations presented above determines the order in which these stages are applied to the component.
The next aspect is the declaration of extension handling ability. Another component (the handler) is declared using the same meta info
model as you have seen above, but in this case, a component is declaring
that it is a handler for a particular lifecycle stage interface.
<type>
<!-- other stuff -->
<!-- declaration of extension handling abilities -->
<extensions>
<extension type="org.apache.avalon.playground.Exploitable" />
</extensions>
</type>Based on the <extensions> tag, the container can register this component type as a condidate handler. During the assembly phase, the container can make assesment of all candidates capable of supporting the Exploitable interface (in the case of multiple candidates, you can include you own selection policy or you can let Merlin take care of this automatically).
During the deployment phase, Merlin will assembly and deploy the selected handler and apply the handler to the deployment of the target component implementation.
* there must be a notion of lifecycle order - is this done asserted at registration ?
This is done in strinct accordance with the declarations by the component that is being handled. In the above examples the Exploitable handler will be invoked ahead of the Demonstratable handler.
[for instance the object might need the data from the servletConfig, for other initialisation work ]
yep - the jboss people are doing this with jaas?Another scenario - access control based on a principal identity. This information is unavailable at deployment time. It's a runtime concern. A proxy can intercept an invocation and do stuff like unmarchal a principal identifier or whatever, pass the argument to some code to handle the business logic (e.g. an access decision), and then apply the invocation to the target. The extendibility issue here concerns the ability to "plug-in" a handler for access control which can be used by the proxy implementation. This is where interceptor chains come into play.
In the Merlin environment the object that actually exposes a proxy is the Appliance (a.k.a. the component deployment handler). An appliance is a component and as such it can have multiple dependencies, context, configuration, etc. This immediately eliminates a bunch of classic problems related to intercept style management - namely the ordering and synchronization of multiple interceptors. However - at least in Merlin, there isn't a way for the container to acquire an interceptor or interceptors without introducing a specialized appliance (but its is an interesting through).
ok. So you see the point of proxies and aspects therefore in the appliance "extension point" (using eclipse terms here ;-) ).
Will be playing with merlin - sounds interesting.
Lets us know how you find it - feedback is very highly appreciated.
Cheers, Steve.
Cheers, Steve.
thanks for your insights,
-- Jakob
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--
Stephen J. McConnell mailto:[EMAIL PROTECTED] http://www.osm.net
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
