-
1. Re: expressing dependent states
adrian.brock May 21, 2008 10:40 AM (in response to jhalliday)You're breaking the MBean rules.
You shouldn't expect some dependency to be started in your create lifecycle.
I'm surprised this worked when you were an MBean? Maybe just luck :-)
The obvious solution would be to inject the ORBService as a parameter
into your create() method. It then must be started/installed to be passed
as such a parameter.<bean ...> <create> <parameter><inject bean="ORBService"/></parametrer> </create>
But if you don't want to change your code then you can use the "demand"
instead of "depends' to achieve what you want:
Example from the schema:
http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbossas/projects/microcontainer/trunk/kernel/src/resources/main/schema/jboss-beans-common_2_0.xsd?view=logThe demand is used to specify a dependency on a supply and when the demand should be supplied e.g.: ISupply must be installed before IDemand is constructed <bean name="IDemand"> <demand state="Instantiated">theSupply</demand> </bean> <bean name="ISupply" ...> <supply>theSupply</supply> </bean>
In your case you would<demand state="Create">ORBService</demand>
-
2. Re: expressing dependent states
jhalliday May 21, 2008 10:47 AM (in response to jhalliday)Injecting it to the create would be fine and will actually save me a JNDI lookup, but ORBService is not a bean it's a JMX MBean. Is injection of those supported?
-
3. Re: expressing dependent states
jhalliday May 21, 2008 10:53 AM (in response to jhalliday)> You're breaking the MBean rules.
> You shouldn't expect some dependency to be started in your create lifecycle.
> I'm surprised this worked when you were an MBean? Maybe just luck :-)
Probably because I've changed the TransactionManager to do more of its setup in create() rather than start(). In my view the real problem is that CorbaORBServer does things in startService() that actually belong earlier in the lifecycle. Pretty much everything other than orb.run() infact. But since there are no real guidelines on what goes where in the lifecycle it's all a matter of opinion. Since it can't be guaranteed that the authors of two entities have the same opinion, there needs to be a flexible wiring of state dependencies. -
4. Re: expressing dependent states
adrian.brock May 21, 2008 11:02 AM (in response to jhalliday)"jhalliday" wrote:
But since there are no real guidelines on what goes where in the lifecycle it's all a matter of opinion.
????
http://wiki.jboss.org/wiki/ServiceLifecycle
But that doesn't mean that people follow the rules. ;-) -
5. Re: expressing dependent states
adrian.brock May 21, 2008 11:12 AM (in response to jhalliday)"jhalliday" wrote:
Injecting it to the create would be fine and will actually save me a JNDI lookup, but ORBService is not a bean it's a JMX MBean. Is injection of those supported?
Yes, it injects the mbean instance. It's equivalent to what we used to do
when we used the getInstance() attribute of an MBean
then do something like:public MyMBean getInstance() { return this; }
If you're just after the ORB, then you can do something like:<create> <parameter><inject bean="ORBService" property="ORB"/></parameter> </create>
or even just inject it as a property on your bean. -
6. Re: expressing dependent states
jhalliday May 21, 2008 11:37 AM (in response to jhalliday)Hmm, presumably injecting it as a parameter to some lifecycle method ensures the property has actually been configured correctly (ORBService may setORB(...) in e.g. startService()), whereas injecting it as a property on the bean does not. Property injection is built on the assumption that a bean's properties are initialized at bean creation time I guess? Besides, if I inject it as a property of my bean, I may be tempted to use it in create() rather than start(), which would be against the guidelines I think. So the correct approach would seem to be
<start> <parameter><inject bean="ORBService" property="ORB"/></parameter> </start>
-
7. Re: expressing dependent states
adrian.brock May 21, 2008 12:07 PM (in response to jhalliday)"jhalliday" wrote:
Hmm, presumably injecting it as a parameter to some lifecycle method ensures the property has actually been configured correctly (ORBService may setORB(...) in e.g. startService()), whereas injecting it as a property on the bean does not. Property injection is built on the assumption that a bean's properties are initialized at bean creation time I guess? Besides, if I inject it as a property of my bean, I may be tempted to use it in create() rather than start(), which would be against the guidelines I think. So the correct approach would seem to be
No. "inject" is different from "depends".
The MC is a lot more flexible than the old service lifecycle.
In fact, the JBoss5 service lifecycle is more flexible than the old JBoss4 one. ;-)
depends is a two phase lifecycle create/start that is backwards compatible with
the old MBean service lifecycle.
The MBean lifecycle was originally done as two phase to solve circular dependency
issues (which most services don't have anyway ;-).
inject works by requiring the dependency is INSTALLED (i.e. it has completed its whole
lifecycle) before the object can be injected into the dependee.
Circular dependencies are handled in a different (more explicit) way in the MC,
see the getting started docs. i.e. You can override what state the dependency
must be in before it is injected.
e.g. You can inject an MBean instance or property into a constructor, propertly, lifecycle
method parameter, etc. and it will guarantee the MBean has been fully started before
that part of the lifecycle gets invoked.
There's a different philosophy between the two mechanisms.
ASIDE:
In JBoss5 MBeans have gained some (but not all) of this injection flexibility
from the ServiceController being implemented on top of the MC.
e.g. There is now a proper lifecycle for the setAttribute() invocations on the
mbeans so they can use "inject" semantics rather than "depends optional-attribute". -
8. Re: expressing dependent states
jhalliday May 21, 2008 12:33 PM (in response to jhalliday)wow, cool.
So in that case injecting it as a property of my bean will give the same value as injecting it as a parameter of a lifecycle method call. The difference I guess is limited to the potential for concurrent execution.
In the case of injection as a bean property, the lifecycles must be strictly serial ordered. Whereas, with lifecycle method parameter injection, the bean on which the injection is occurring can go through any of the lifecycle phases before the one for which it requires the injected parameter, concurrently with the lifecycle of the bean that will be injected.
Is that right? Does MC actually use or plan to use concurrent startup to speed things up? If so, there is potential advantage in sticking with parameter injection rather than injecting it as a property on my bean. -
9. Re: expressing dependent states
adrian.brock May 21, 2008 12:59 PM (in response to jhalliday)"jhalliday" wrote:
Is that right? Does MC actually use or plan to use concurrent startup to speed things up? If so, there is potential advantage in sticking with parameter injection rather than injecting it as a property on my bean.
Yes, but I don't really see how delaying the injection increases the concurrency?
In most circumstances if you have dependencies they are going to wait until
you are fully installed so it doesn't really matter if you inject some other service
into a property or a lifecycle method.
On an aesthetic point, some advocates of IOC (e.g. nano/pico container) suggest
you should inject into the constructor parameters since then you can
be immutable and it is less error prone (you are forced to inject all the parameters
while people are not forced to set all the properties or configure lifecycle methods). -
10. Re: expressing dependent states
alesj May 21, 2008 7:32 PM (in response to jhalliday)You can add 'state' attribute to inject, meaning you want your injectee to be in/past that state - in your case you would put Start:
<bean ...> <create> <parameter><inject bean="ORBService" state="Start"/></parametrer> </create>
-
11. Re: expressing dependent states
alesj May 21, 2008 7:42 PM (in response to jhalliday)"adrian@jboss.org" wrote:
But if you don't want to change your code then you can use the "demand"
instead of "depends' to achieve what you want:
In your case you would<demand state="Create">ORBService</demand>
That's not entirely true, since it doesn't do all/exactly what Jonathan asked. ;-)
In this case he's missing dependent state configuration.
He's forced to have ORBService in Installed state, which is something he might not want since he's fine with just Start.
The demand notion is not the right place for this, since demand/supply concept handles things beyond contexts handled by MC - a generic match mechanism. And as such some items we demand might not have dependent state.
Should we create new context-demand notion? -
12. Re: expressing dependent states
alesj May 22, 2008 1:51 AM (in response to jhalliday)"alesj" wrote:
..., since demand/supply concept handles things beyond contexts handled by MC - a generic match mechanism. And as such some items we demand might not have dependent state.
This part is wrong, or at least it doesn't explain the real problems behind our demand/supply.
First, items *do* have dependent state, since every supply is backed-up by a kernel controller context.
It's the way we have it implemented.
Currently we add/register all supplies from BeanMetaData at Installed state. So no way of knowing if some supplier can supply the supply before (a lot of supplies here :-).
We can extend the supply notion in a similar way we extended installs, to be applicable in any state.
Then havingMap<ControllerState, Map<Object, List<KernelControllerContext>>>
in AbstractKernelController."alesj" wrote:
Should we create new context-demand notion?
Definitely not. :-)