I'm coming along ok but the invocation chain is one of the reasons why I asked about the roadmap.
Anyhow, look at:
in CVS the opcodes are only for dynamic mbean but my intention is that *all* operations on any type of mbean are also listed here. i.e. an opcode for NotificationBroadcaster.addNotificationListener etc etc.
The idea is that we can intercept on absolutely anything and interceptors just do a switch() on the opcodes they are interested in. Your mmbean stuff is unlikely to be interested in anything other than invokes and attribute calls.
However, this means that the "make everything look like a DynamicMBean" strategy for dispatching calls from the mbeanserver to an mbean will disappear. Instead we'll have, "everything looks like a dispatcher".
I'm moving this way because the "everything is a DynamicMBean" sucks due to interface overlap - the one that springs to mind is how DynamicMBean.getMBeanInfo contains values from an optional interface (NotificationBroadcaster).
So if you want to understand what it's looking like, imagine MBeanTarget was actually called DynamicMBeanDispatcher. Then imagine a ReflectedMBeanDispatcher (or BCELMBeanDispatcher) which extended MBeanInterceptor and did the dispatch work similar to MBeanAdapter.
Wow, I can't beleive I wrote that.
I can commit late tonight and I hope you're not tearing your hair out over what I've just written...
I am vexed by what I'm doing.
It will mean that the MBeanServer will create an MBeanInvocation to pass to an mbean's dispatcher.
For StandardMBeans it'll be fine.
For DynamicMBeans it will look like a useless extra step except for, where hooks exist, we can put interceptors in front of them.
For ModelMBeans, the DynamicMBeanDispatcher will unpack the MBeanInvocation and direct the call to the relevant method (just like MBeanTarget does today) on the MMBean. Then the MMBean creates *another* MBeanInvocation to give to the head of the interceptor chain that eventually ends with a Reflected|BCEL dispatcher.
I keep latching on to the desire to allow interceptors to go in front of any type of MBean. I may just stick with using DynamicMBean as the mbeanserver-visible invocation interface for standard mbeans and give up on being able to put interceptors between the mbeanserver and std/dynamic mbeans.
> For DynamicMBeans it will look like a useless extra
> step except for, where hooks exist, we can put
> interceptors in front of them.
should we put interceptors in front of dynamic mbeans or leave implementing interceptors up to the dynamic mbean implementor?
> For ModelMBeans, the DynamicMBeanDispatcher will
> unpack the MBeanInvocation and direct the call to the
> relevant method (just like MBeanTarget does today) on
> the MMBean. Then the MMBean creates *another*
no extra object creation in the invocation chain, no, bad bad bad... why you need this?
> to give to the head of the interceptor chain that eventually ends with a
> Reflected|BCEL dispatcher.
> I keep latching on to the desire to allow
> interceptors to go in front of any type of MBean. I
> may just stick with using DynamicMBean as the
> mbeanserver-visible invocation interface for standard
> mbeans and give up on being able to put interceptors
> between the mbeanserver and std/dynamic mbeans.
hmm.. ? what does the interceptors have to do with the type of mbean?
this all sounds way too complex. The invocation is a simple beast, don't over-do it
the ModelMBean implementation is an invoker... so it is the first thing at the head of the invocation stack... so far so good, it looks like it's an easy transition from the OLDMBeanInvoker (just need a no args constructor, as the MMB won't know the stack config at object creation time, only at registration time).
Now at the end of the chain you have the target... problem there as it requires a DynamicMBean instance, and all the MMB has is an object as its target... now do I need to create a target instance that wraps the MMB object and implements the dynamic interface? how do you deal with this when a std mbean is registered?
oh, that's where you put the adapter, dont you? you sneaky dog you
ok, so we need to have the MMB resource object reference as part of the invoker (this was in OLDMBeanInvoker). Then in MBeanCapability we check if someone is trying to register an invoker directly to the server... in which case we take the resource object as the end target (modelmbean template model), provided it is non null (otherwise we won't play), instead of the mbean itself (std & dyn mbean model).
Let's see what happens...
What what what?
"register invoker directly in the server"... OK this is where I'm freaking out (maybe in a good way).
Are you suggesting that we *do* use Invoker as the interface that the MBeanServer uses?
Are you also suggesting that in the call to MBeanServer.registerMBean() we see if the object instanceof org.jboss.blah.Invoker and if so, we use it directly (Std/Dynamic would have invokers/chain constructed).
If so, then that (in one fell swoop) unifies the location of the invoker/interceptor chain and leaves me much less vexed.
Have I got the picture?
well there seems still be a problem here as in the current code base I don't see a way how an invoker can configure all of its interceptor stack (all the way to the last 'ceptor)... in other words if I have an XMBean (which is the invoker, yes) I *must* be able to configure the complete stack from within the XMBean, without relying the MBean server to plug in the last target.
Otherwise we lock the model mbean implementations to our server, and I don't want that. They need to be able to move.
Am I missing something obvious here?
I'm sorry. I'm really frazzled and I'm feeling a little bit slow today (no hangover as an excuse tho ;-) )
I'm losing track of terminology, especially after I remembered that there is an MBeanInvoker that implements DynamicMBean - urgh. So let me be really clear:
In MBeanEntry we have:
Instead of getMBean() I was thinking about:
Where Invoker was the head of an interceptor chain and *only* had the following method for dispatching *any* calls:
Object invoke(MBeanInvocation) throws InvocationException
I.e. whenever the MBeanServer wanted to dispatch a call, whether it be setAttribute or invoke or addNotificationListener, it would pass that call (encapsulated in an MBeanInvocation) through the invoker/interceptors.
Ok, now you can tell me whether I'm getting the picture or not.
> What what what?
> "register invoker directly in the server"... OK this
> is where I'm freaking out (maybe in a good way).
> Are you suggesting that we *do* use Invoker as the
> interface that the MBeanServer uses?
no, the server can still only see the dynamic or modelmbean interface. Invoker is the implementation of this interface. But we need to be able to configure all of the invocation stack/chain/whatever from within the invoker, and not rely MBeanServer do any configuration for us (setting end targets).
I will need to sleep on this (I've been up almost 36 hrs). I'll get back to you tomorrow.
Our two attitudes towards this are not mutally exclusive.
I know how to make this work. Get some rest, the outlook is rosy.
Hope you're rested. My ISDN line crapped out late last nite so no commit. I'm told it's up and running now but I won't be home 'till late.
I figured out how to support the desire for XMBean portability, the requirement for the XMBean to own all of it's interceptors with no mbeanserver involvement and unified the interface the mbeanserver uses to talk to the mbeans (while leaving open the possibility of mbeanserver-configured interceptors at a later date).