Hi,
Okay - after playing with your code for a while, heres my current thoughts.
On Thu, 22 Aug 2002 01:18, Igor Fedorenko wrote:
> During implementation of the block factories I've got a few issues I
> would like to discuss.
>
> First, it is not clear to me if block factories belong to applications
> or to the kernel.
My impression is that Factories are generally something that a user may want
to use and thus they should really be in "userland". However while we are
"evolving" them I think it is best we keep them in "kernel" land. That way we
can change them with little regard to backwards compatability - at least
until we move them back into userland. Thoughts?
Then again it may only be "power" users who use factorys so we may be able to
get away with a set of them in kernel and just having the implementation keys
point to sufficently detailed descriptors.
>Here are my pros and cons
> Factories are part of applications
> Pro: factories provide application specific logic to initialize blocks
> thus they belong to applications
> Con: factories provide application metadata (specifically, BlockInfo)
> this means they must be up-and-running before an application is started.
> Initialization of factories as part of application startup has following
> problems - factories' lifecycle needs to be managed separately from
> other application blocks; it is difficult to verify application
> consistency due to the fact that factories must be started before rest
> of the application is even assembled.
We already handle listeners differently and the next rev of the kernel will
likely handle lots of different styles of components. So we can build it with
this in mind. We could easily make it so that
* all factorys get started, then
* all listeners get started, then
* all blocks get started
> Second, implementation of objects returned from
> BlockFactory#createObject gets pretty ugly.
> To describe the problem better let me introduce usage scenario we can
> talk about. My test system consists of two JVM (JVM-A and JVM-B). JVM-A
> runs MX4J MBeanServer and has "mydomain:name=mybean" mbean of type
> test.MyMBean and JRMP adaptor for remote access. JVM-B run phoenix
> application which has block "jmx-client" that needs services provided by
> "mydomain:name=mybean". Both JVM-A and JVM-B have same lifetime, i.e.
> they both started and stopped simultaneously. Lets also assume that
> JVM-B has "remote-jmx-server" block that provides service
> "mx4j.connector.RemoteMBeanServer" and knows how to connect to JVM-A.
> Problem: write and deploy "remote-mbean" block that provides service
> "test.MyMBean" to JVM-B.
> The issue is that "remote-mbean" block needs to implement service
> interface which is not known at block's compile time as well as a number
> of avalon's interfaces (Serviceable in particular). My original proposal
> had new phoenix interface "org.apache.avalon.phoenix.Invokeable" which
> extends "java.lang.reflect.InvocationHandler". Implementation of this
> interface informs phoenix that it should call block.invoke(..) when
> somebody wants to use block's services. Now I also want to introduce yet
> another interface "org.apache.avalon.phoenix.ProxyProvider" that'll have
> single method "Object getProxy()" and will serve same purpose as
> Invokeable but use proxy object provided by the block.
I am not sure I entirely follow this. But let me just get this straight. We
have a local block that is dynamically defined to implement some interface
"MyRemoteService" - which it does not know at compile time?
I think I would like to see that solved in the followin manner. Each factory
is responsible for defining the object in whatever way they see fit. The end
result is just that the object coming out of the factory must implement the
service interfaces and any avalon interfaces it needs to implement.
This way, both proxy and Invokable become implementation details of the
factory rather than part of the phoenix API layer. So your factory would end
up having a method like
public Object createBlock( ... )
{
MyBlockDelegator delegator = ...;
//delegator is serviceable
Class remoteInterface = determineRemoteInterface();
myInvocationHandler = new ...;
Class[] api = new Class[] { Serviceable.class, remoteInterface };
return Proxy.newProxyInstance( classloader, api, myInvocationHandler );
}
By doing it this way, we only have to get the factory API right and we can
experiment to our hearts content whether to use proxys, or Invocable or
whatever really. Like?
> PS: I only wonder why do my messages are getting so long?
keep em coming ;)
--
Cheers,
Peter Donald
*-----------------------------------------------------*
* "Faced with the choice between changing one's mind, *
* and proving that there is no need to do so - almost *
* everyone gets busy on the proof." *
* - John Kenneth Galbraith *
*-----------------------------------------------------*
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>