-
1. Re: Handling contexts in error
adrian.brock Feb 20, 2008 8:10 AM (in response to alesj)"alesj" wrote:
We could enable the push from Error or just add some more info that this is not what the user should do.
You can't push from error for at least three reasons:
1) In a manual process, you'll have people doing:
change(state1); // This errors
change(state2); // This will error again (pointlessly)
Even worse, it will do the wrong thing at undeploy
deploy:
change(state1); // ok
change(state2); // error -> undeployed
undeploy: (reversing the state machine)
change(state1); // so it has now deployed to state1 during an undeploy????
2) The above can happen transitively where changing the state of one context will
try to push other contexts that depend on it and are now satisfied by
the changed state (again leading to lots of errors)
3) If you change the metadata like you say, then you are supposed to re-install.
Like I've being saying on other threads, we should be cloning that metadata
so your change in the above example would have no effect anyway.
If the deployment has errored then it has gone. The context is only retained
for error summary purposes.
If there was no need for the IncompleteDeploymentException then an
error would have been defined to uninstall.
It's also potentially problematic if somebody changes the BeanMetaData
in a incompatible way midway through the deployment process
which is another reason why we should avoid "out-of-band" changes,
we should require a re-install. -
2. Re: Handling contexts in error
julien1 Feb 20, 2008 8:32 AM (in response to alesj)So actually Ales is trying to explain a use case that I need MC to handle for me. Suppose we have the POJO:
public class Bean { private int count = 0; public void start() throws InitializationException { if (count++ == 0) throw new InitializationException(); } }
Can MC handle a use case where the failure is not trigerred by its initial state (bean meta data if I understand correctly) like in the use case I am posting ?
How can I handle the following transitions:
NOT_INSTALLED -> CREATE -> start() -> ERROR -> start() -> INSTALLED
if the Bean I listed above is reinstantiated every time it will fail whatsoever. If the same instance is used then it will fail only the first time.
Please try to get an answer understandable by someone that has little knowledge about MC. -
3. Re: Handling contexts in error
adrian.brock Feb 20, 2008 8:54 AM (in response to alesj)"julien@jboss.com" wrote:
Please try to get an answer understandable by someone that has little knowledge about MC.
This isn't really an MC question, it's a programming patterns question :-)
The answer is to use a factory/singleton pattern.
e.g. These two would use the object constructed by MyFactory
(which can also be an instance class rather than the shown static method).<bean name="Bean1"> <constructor factoryClass="MyFactory" factoryMethod="getInstance"/> </bean> <bean name="Bean2"> <constructor factoryClass="MyFactory" factoryMethod="getInstance"/> </bean>
ALTERNATIVE:
If you don't like the boiler plate of coding a singleton factory,
I wrote an aspect that does it for you:
http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbossas/projects/aop/trunk/aspects/src/main/org/jboss/aspects/patterns/singleton/Singleton.java?revision=63048&view=markup
which I guess could also be configured with an annotation (although it doesn't exist currently).<bind pointcut="execution(@com.acme.Singleton->new())"> <advice name="constructorAdvice" aspect="Singleton"/> </bind> @com.acme.Singleton public class MyBean {}
I'm sure you can adapt it to your needs if it doesn't do exactly what you want. ;-) -
4. Re: Handling contexts in error
adrian.brock Feb 20, 2008 9:01 AM (in response to alesj)"adrian@jboss.org" wrote:
<bind pointcut="execution(@com.acme.Singleton->new())"> <advice name="constructorAdvice" aspect="Singleton"/> </bind> @com.acme.Singleton public class MyBean {}
I think this pointcut language is wrong, since it requires you to annotate the constructor
rather than the bean?. But I'm sure you can lookup the correct syntax in the aop docs. ;-) -
5. Re: Handling contexts in error
julien1 Feb 20, 2008 9:06 AM (in response to alesj)ok I see.
the other use case it does not answer is that, I need to have some Container bean that list all the related failed POJO to show that it is possible to restart them so:public class Container { private Set<Contained> containeds = new HashSet<Contained>(); public void addContained(Contained contained} { // trivial } public void removeContained(Contained contained} { // trivial } public Set<Contained> listContainedThatFailed() { // trivial } }
public class Contained { private Container container; public void setContainer(Container container) { // Will be removed when it is possible to do install/uninstall on a specified state, ideally would be instantiated (instead of installed), Ales told me he is working on that feature if (container != null) { container.addContained(this); } else { this.container.removeContained(this); } this.container = container; }
so admin could browse the "failed" beans and attempt to restart some of them using the admin tool, or in a programmatic wayfor (Contained contained : container.listContainedThatFailed()) { contained.invokeStart(); }
I think that the whole point is that I need to consider a bean in the 3 following states:
stop/installed/failed
and trigger trnasitions :-)
where invokeStart() delegates to// Here controllerContext is the one of the failed bean controller.change(controllerContext, ControllerState.INSTALLED);
-
6. Re: Handling contexts in error
adrian.brock Feb 20, 2008 9:35 AM (in response to alesj)I don't really understand what you are trying to do?
Guessing...
INSTALL - MC wiring
The add/removeContained looks like either the install or installCallback stuff.
However, if a bean goes to the error state then it will have its uninstall or
uninstallCallback invoked. There's no notion of holding onto a broken bean
(except for error reporting - see above).
CONTROLLER - a bit more control for yourself
If you want to control the states manually then consider writing your own
facade over the MC controller, e.g. take a look at what the ServiceController
(in the jbossas system-jmx project) does to support the legacy JMX api.
i.e. http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbossas/trunk/system-jmx/src/main/org/jboss/system/ServiceController.java?revision=64966&view=markup
* stopping and starting mbeans from the mbean's own jmx operations
mbeanserver.invoke() -> mbean.stop() -> servicecontroller.stop() -> MC
* emulating the old SAR deployer or programmatic use of the ServiceController
to manually change the mbean states
* maintaining the legacy ServiceContext and listing them by state
http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbossas/trunk/system-jmx/src/main/org/jboss/system/ServiceContext.java?revision=65327&view=markup
e.g.List<ServiceContext> listIncompletelyDeployed() {...}
etc.
For your usecase, it doesn't sound like it needs to be as complicated
as the JMX stuff, but the "invokeStart() delegates to" sounds like a facade/wrapper
to me? -
7. Re: Handling contexts in error
adrian.brock Feb 20, 2008 9:49 AM (in response to alesj)"adrian@jboss.org" wrote:
There's no notion of holding onto a broken bean
(except for error reporting - see above).
Maybe we could add a notion of errorCallback?
i.e. if a bean errors during the startup process then we would invoke this callback,
something like:public class Container { @Install public void addContained(Contained contained} { // trivial } @Uninstall public void removeContained(Contained contained} { // trivial } @Error public void addError(Contained container) {} @Removed public void removeError(Contained container) {} }
The @Removed is because the only time it will go out of the error state
is when it is removed altogether from the controller during the redeploy.
But this seems a bit hacky to me? It's looking less like a POJO
and more like what the class says it is a "Container" ;-)
Perhaps a better approach would be for you to register for events
on your "contained" contexts, so you would actually receive:
Pseudo code// Your api removeContained(contained); // Out-of-band notifications from the MC errorOccurred(contained, throwable); // Out-of-band notication from the MC at redeployed uninstalled(contained); // Re-installed using your api addContained(contained);
-
8. Re: Handling contexts in error
julien1 Feb 20, 2008 11:28 AM (in response to alesj)Here is my use case:
I defined an SPI for that allow to integrate portlet applications / portlet container and portlet filter objects (which have a stop/start/failed life cycle and start() throws Exception / stop() callbacks) with kernel system (whether it is MC or something else).
I have two facade of objects:
1/ managed object which are exposed to admin and allow to know what exists, the state and life cycle trigger (managedStart() / managedStop())
base class ispublic interface ManagedObjet { ManagedObjectStatus getStatus(); void managedStart() throws Exception; void managedStop(); }
then for instance I havepublic interface ManagedPortletApplication extends ManagedObject { Collection<ManagedPortletContainer> getPortletContainers(); }
public interface ManagedPortletContainer extends ManagedObject { ManagedPortletApplication getPortletApplication(); }
-----------------------------------
Then I have the internal API that is aimed at providing wiring capabilities and real start/stop activitiespublic interface PortletContainerService { void setPortletApplication(PortletApplicationService pa); void start() throws Exception; void stop(); }
public interface PortletApplicationService { void addPortletContainer(PortletContainerService pc); void removePortletContainer(PortletContainerService pc); void start() throws Exception; void stop(); }
-----------------------------------
Now I am trying to get an MC implementation of the Managed* stuff that uses JBoss MC to:
1/ manage the *Service objects (wiring and callbacks)
2/ provide a managed interface to know about what exists and managed their life cycle
3/ be integrated with other MC beans that may exist in the same Kernel (so it is possible to create dependencies between a portlet container and another service, etc...) -
9. Re: Handling contexts in error
adrian.brock Feb 20, 2008 12:24 PM (in response to alesj)The MC can do all this, except the failure part.
The reason it can't do the failure part is because it follows what is an accepted
generally good programming practice (e.g. ejbs do the same)
that if the container invokes a bean and it throws an error then you discard
that bean. You can't know that the bean is still in a good state because
you don't know why it threw the error.
PROPOSAL
I've had a seperate thought which is probably more acceptable to both
you and to me, ;-)
What you really want to do is manage the state of the failed beans.
i.e. you want to takeover the management of the context in error from the MC
and fix it manually.
So my solution would be to allow something like:
xml pseudo code as always ;-)<bean ... error-handling="manual"/>
If for example the bean threw an error in start() then we no longer just discard
this bean. Instead we would effectively change its controller mode to "manual"
(if it isn't already) and just then revert it to the previous state. i.e. Created in this case
or back to Instantiated if the property configuration failed.
You can then pick up the management of the bean from there.
When you decide to move the bean, we would just clear the error in the
controller context and try again (reverting back to automatic if the bean
was previously in that mode).
We would never try to move a context in such a state without an
explicit request on the controller to do so.
I don't think this would require a major change in the Controller,
most of the work would be in the IncompleteDeploymentException
where we would now have to check all contexts at all states
to see whether it has an error set (previously we just retrieved those
in the **ERROR** state).
We may want to only allow this for checked exceptions. i.e. if start throws
a RuntimeException or Error, we would still discard the bean
or perhaps make it configurable?
This semantic would deal with my objections above and give you the
ability to manage the failing beans/contexts without having to re-install them. -
10. Re: Handling contexts in error
julien1 Feb 20, 2008 1:22 PM (in response to alesj)Actually the way I am using it is rather dynamic and it creates metadata at runtime using the Kernel metadata stuff and does not use XML or Annotations.
I guess that what I have can be considered as a "deployer" (i.e take meta data and create a set of runtime kernel managed objects). -
11. Re: Handling contexts in error
julien1 Feb 20, 2008 2:09 PM (in response to alesj)The reason it can't do the failure part is because it follows what is an accepted
generally good programming practice (e.g. ejbs do the same)
that if the container invokes a bean and it throws an error then you discard
that bean. You can't know that the bean is still in a good state because
you don't know why it threw the error.
this is the programming model that is designed as such.
If you take Servlet or Portlet (modelled after Servlet) it is not the same and it is more like a service programming model. -
12. Re: Handling contexts in error
adrian.brock Feb 21, 2008 6:47 AM (in response to alesj)"julien@jboss.com" wrote:
Actually the way I am using it is rather dynamic and it creates metadata at runtime using the Kernel metadata stuff and does not use XML or Annotations.
That's fine. There would just be a BeanMetaData::getErrorHandlingMode()
which would get copied into a ControllerContext::setErrorHandlingMode(ErrorHandlingMode)public enum ErrorHandlingMode { DISCARD, // The default as now MANUAL, // What you want MANUAL_CHECKED, // As manual but RuntimeExceptions, Errors lead to a DISCARD }
That's why I called it "pseudo xml" :-) -
13. Re: Handling contexts in error
julien1 Feb 21, 2008 7:06 AM (in response to alesj)Ok,
for now I am formalizing the API/SPI I talked about, did an implementation that I can use meanwhile (that would be reused in JBoss Portal + JBoss AS 4.2 anyway) and most importantly writing test cases to assert the correct behavior of the implementation.
once it is done, I will probably collaborate with Ales to get an MC implementation that pass the same unit tests.
It will take me a couple of days before it is done and the MC implementation is a longer term effort but it would be of course nice to get it implemented in the same MC used by AS 5. -
14. Re: Handling contexts in error
alesj Mar 27, 2008 10:51 AM (in response to alesj)"adrian@jboss.org" wrote:
PROPOSAL
I've had a seperate thought which is probably more acceptable to both
you and to me, ;-)
What you really want to do is manage the state of the failed beans.
i.e. you want to takeover the management of the context in error from the MC
and fix it manually.
So my solution would be to allow something like:
xml pseudo code as always ;-)<bean ... error-handling="manual"/>
If for example the bean threw an error in start() then we no longer just discard
this bean. Instead we would effectively change its controller mode to "manual"
(if it isn't already) and just then revert it to the previous state. i.e. Created in this case
or back to Instantiated if the property configuration failed.
You can then pick up the management of the bean from there.
When you decide to move the bean, we would just clear the error in the
controller context and try again (reverting back to automatic if the bean
was previously in that mode).
We would never try to move a context in such a state without an
explicit request on the controller to do so.
I don't think this would require a major change in the Controller,
most of the work would be in the IncompleteDeploymentException
where we would now have to check all contexts at all states
to see whether it has an error set (previously we just retrieved those
in the **ERROR** state).
We may want to only allow this for checked exceptions. i.e. if start throws
a RuntimeException or Error, we would still discard the bean
or perhaps make it configurable?
This semantic would deal with my objections above and give you the
ability to manage the failing beans/contexts without having to re-install them.
Are there any other hooks (api changes), apart ErrorHandlingMode enum, you've had in mind?
Picking up bean in the Controller can be done with Controller::change.