Laurent Rieu wrote:

Currently the implementation is not proxying the component interface
because some additional thinking is required on (a) services that are
classes as opposed to interfaces, and (b) the resulting need to declare
a proxy policy. The issue here is that we cannot create a proxy if a
service class is not an interface.



One possible solution to this could be to use bytecode generation instead of the standard JDK dynamic proxy stuff. There is the CGLib library that is pretty good and allows to dynamically create a proxy over a class provided it is not declared as final. Maybe worth trying it, and why not build a small abstraction layer over the proxy generation code so that switching implementation would not break the whole castle ?


The approach sound interesting. I've certainly been bashing my head against the restrictions in the standard JDK classes.


Concerning an abstraction layer - I think there is room improvement in the current object model - the proxied service should be generated by the lifestyle handler but this is not so convinient under the current implementation (a particular type of lifestyle handler is instantiated by the appliance based on policies declared in the meta and lifestyle operations are delegated to the handler).

An alternative approach would be to use an abstract appliance as a base class and have different appliance types for the different lifestyle policies extend the abstract appliance. Proxy operations could managed more elegantly at the abstract appliance level.

Maybe I neeed a whiteboard!

Cheers, Steve.


Laurent


----- Original Message -----
From: "Stephen McConnell" <[EMAIL PROTECTED]>
To: "Avalon framework users" <[EMAIL PROTECTED]>
Sent: Thursday, June 12, 2003 6:03 PM
Subject: Re: [merlin] URL block protocol




Laurent Rieu wrote:



Ok, I'm starting to get it.

So you're saying that Merlin always has a root block addressable via "/",
but this root block has no real name, hence my problems trying stuff like
"/root" as I expected the root block to be called "root". I actually have


no


real preference between having this root block unamed or having it always
started and referenced as "root". I guess it would probably make it


clearer


if you always have a root block named "root".



The real question I have here is if we want to be able to add and remove
blocks dynamically.  If we want to do this them Merlin should be
creating the root and any user supplied block should be installed as a
subsidiary of the root block.  With this approach, the "/" name makes
sence.



What makes me think is that #<interface-name> part you can add to a URL


to


have access to services exported by a block. Why do you treat blocks
differently from the components it contains, as a block is also a


component


?



A block is treated differently because it can isolate services that are
part of the implementation and not intended for publication outside of
the block.



Maybe could Merlin understand the following url [base-url]/root/myblock


as


an access to the block myblock and all the services it exports, meaning


the


requester has to cast the returned object to the interface he / she


expects,


provided of course that the returned object implements all the interfaces
(services) declared in the descriptors. I guess you're using dynamic


proxies


to represent the services exported by a block.



That's correct.



This dynamic proxy could
implement ALL the interfaces that a block export, leaving the cast


operation


to the user.



This is how it works now - this enables a block to act as a service
provider to other components.  The incomming invocations are delegated
to the components the actually provide the services - as such - the
block simply looks and behaves like a component.




I think this is exactly what is done when you request a
"normal" component (ie not a block). A component exports services, and


when


you get that component from the container, it implements ALL the


interfaces


that are declared in the component descriptor. Otherwise (to remain
coherent), you can proxify EVERY component that are returned by the
container and make them implement either ONE interface (the interface


beinig


specified by the #<interface-name> part of the URL) or ALL interfaces


(when


nothing is specified in the URL). This would allow the following URL :

[base-url]/root : returns the root block as a component (proxy)


implementing


all the interfaces it exports.



Yep.
Current behaviour.



[base-url]/root#my.package.MyService : returns the root block as a


component


(proxy) implementing the MyService interface (provided this root block
really exports the MyService interface)



This could be done.
Would require some tweaking of the StandardBlock.getVirtualService(
Object source, String ref ) implementation.



[base-url]/root/mycomponent : returns mycomponent contained in the root
block. This component implements all the interfaces it declares in its
deployment descriptor



Currently the implementation is not proxying the component interface
because some additional thinking is required on (a) services that are
classes as opposed to interfaces, and (b) the resulting need to declare
a proxy policy.  The issue here is that we cannot create a proxy if a
service class is not an interface.



[base-url]/root/mycomponent#my.package.MyOtherService : returns


mycomponent


contained in the root block. This component implements the MyOtherService
interface (provided this component really provides the MyOtherService
interface).



This could be done.



Merlin could do some checking to see if a requested component implements


the


Service interface it is asked for. Proxying component allows returned
objects to be narrowed to what the user really expects, hiding the


technical


/ undesirable details Merlin needs in its internals (useful for block
component). Proxying components could also allow some technical plumbing,
but that is another topic ;-)

What do you think ?



If you can patch the StardardBlock proxy management, I can dig into the
root block question and enhance how this is managed (stuff at the
kernel, block loader level).

Cheers, Steve.



Laurent


----- Original Message ----- From: "Stephen McConnell" <[EMAIL PROTECTED]> To: "Avalon framework users" <[EMAIL PROTECTED]> Sent: Thursday, June 12, 2003 1:48 PM Subject: Re: [merlin] URL block protocol






Hi Laurent:

The info your requesting:

The root block is addressable via "/"
Sub-blocks are addressable via "/<block-name>/<block-name>
A service exported by a block is available via appending
#<interface-name> to the URL.

Laurent Rieu wrote:





Hi,

I'm guessing that as the JNDI-zed way to access services is not that




mature,




I have to do with the URL-ized way.





Its a minimal first cut.  The better approach is a full JNDI
implementation that handles the block protocol without requiring any
Merlin API references.






According to the
BlockURLHandler.parseURL() javadoc, Block URL are supposed to conform


to




one




of the following patterns:
block://localhost/root#org.apache.playground.Demo
block://localhost/root/subcontainer/demo





/root#org.apache.playground.Demo

This is addressing a top level component (or container) named root.
This is not the same as addressing the top level container which is
named "/".





Well, I'm having a single component deployed twice in two different
containers, the root one and a 'test' one, as shown in the following
block.xml file:

<block>
 <info>
 <name>root</name>
 </info>
 <implementation>
     <component name="resource-manager"
     class="test.services.resources.ResourceManagerImpl"
activation="startup">
     </component>
     <container name="test">
         <component name="resource-manager"
         class="test.services.resources.ResourceManagerImpl"
activation="startup">
         </component>
     </container>
 </implementation>
</block>

Fist, what's about this 'root' container ?





The name of a block is only relevant for sub containers.
There is an open question here - should Merlin establish a root
container by default?  In which case your assumptions o9n addressing
would have worked.  My feeling is that maybe we should do this - i.e.
establish a root block automatically then add blocks and componets to
the root.





Is it an implicit name (which has
nothing to do with the actual block name as declared in the block.xml




file




?).





Yes.





The fact is that trying to use the URL pattern
[kernelURL]/root/resource-manager it looks like Merlin doesn't know


about


the 'root' path as shown in the stack trace below :





<snip/>





This works when I remove the 'root' element in the URL
(([kernelURL]/resource-manager).





Yep - because your now addressing the top level block.





The following URL don't work either (maybe that is what's expected, but


a


litte documentation about the URL pattern would help ;-) ) :
[kernelURL]/root#test.services.resources.ResourceManager





Because /root addresses a container or component named root containered
within the top level container.





(test.services.resources.ResourceManager being the service interface
exported by my component)
[kernelURL]/root#test.services.resources.ResourceManagerImpl
[kernelURL]/#test.services.resources.ResourceManager
[kernelURL]/#test.services.resources.ResourceManagerImpl
[kernelURL]/test#test.services.resources.ResourceManager
[kernelURL]/test#test.services.resources.ResourceManagerImpl

Actually, the only URLs that work seem to be:
[kernelURL]/resource-manager
[kernelURL]/test/resource-manager

Laurent (who thinks this URL pattern should be clarified !)





:-)

Maybe should add an implict block as "/" so that /root makes sence)
What are you thoughts on this?

SJM

--

Stephen J. McConnell
mailto:[EMAIL PROTECTED]
http://www.osm.net

Sent via James running under Merlin as an NT service.
http://avalon.apache.org/sandbox/merlin



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]






************************************************************************ Ce message a ete inspecte par un anti-virus

Nous vous rappelons que la taille des messages ne doit pas depasser 1.5


Mo


************************************************************************

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]







--

Stephen J. McConnell
mailto:[EMAIL PROTECTED]
http://www.osm.net

Sent via James running under Merlin as an NT service.
http://avalon.apache.org/sandbox/merlin




--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]






************************************************************************ Ce message a ete inspecte par un anti-virus

Nous vous rappelons que la taille des messages  ne doit pas depasser 1.5 Mo
************************************************************************

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]






--


Stephen J. McConnell
mailto:[EMAIL PROTECTED]
http://www.osm.net

Sent via James running under Merlin as an NT service.
http://avalon.apache.org/sandbox/merlin




--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to