Go for it.
IMO the stop should exactly undo what start does. No other cleanup should be necessary.
david jencks
On Tuesday, August 12, 2003, at 09:00 PM, Greg Wilkins wrote:
OK, I have an initial patch for this ready. I can commit it myself, but I wanted to post it as a warning as it has a few unresolved issues.
I have implemented the JSR77 state model in Component and AbstractComponent
For start and stop this was simple. But I have also removed the create and destroy methods for now. I moved any create operations I found to the start() (or doStart()) methods.
I have left destroy methods in the code, but noted that they are currently not supported by the lifecycle. I think they do contain good cleanup code - but we could just rely on java finalize mechanism? Or we could move the code into doStop to be symmetric with doStart.
I have implemented startRecursive in ContainerImpl - however, I really
think that we need an AbstractContainer class for this. But this
would need a method for iterating over children in the Container interface.
As this is not there - I have not done this... more reading of JSR77 spec
required to support their container naming and methods I think?
In JSR77 there is no stopRecursive method - so ContainerImpl.stop is actually recursive (which I think is the correct thing to do?) Again this should be in AbstactContainer.
I'll give this a few hours for "DON'T DO IT" reponses and if I don't get them I'll do the commit and we can work on the remaining issues.
-- Greg Wilkins<[EMAIL PROTECTED]> Phone/fax: +44 7092063462
Mort Bay Consulting Australia and UK. http://www.mortbay.com
Index: modules/core/src/java/org/apache/geronimo/common/> AbstractComponent.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/ geronimo/common/AbstractComponent.java,v
retrieving revision 1.2
diff -r1.2 AbstractComponent.java
58d57
<
68,69c67,70
< public class AbstractComponent implements Component {
< private State state = State.NOT_CREATED;
---public class AbstractComponent implements Component { private State state= State.STOPPED; private long startTime;71c72 < protected Log log = LogFactory.getLog(getClass()); ---protected Log log= LogFactory.getLog(getClass());73c74,75 < public State getState() { ---77,91c79,178public State getState() {
< public final Container getContainer() {
< return container;
< }
<
< public final void setContainer(Container container) {
< if (state != State.NOT_CREATED && state != State.DESTROYED) {
< throw new IllegalStateException("Set container can only be called while in the not-created or destroyed states: state=" + state);
< }
< if (state == State.NOT_CREATED && container == null) {
< throw new IllegalArgumentException("Interceptor has not been created; container must be NOT null.");
< }
< if (state == State.DESTROYED && container != null) {
< throw new IllegalArgumentException("Interceptor has been destroyed; container must be null.");
< }
< this.container = container;
---/**94,98c181,183
* Set the Component state.
* @param newState
* @throws IllegalStateException Thrown if the transition is not supported by the JSR77 lifecycle.
*/
protected void setState(State newState) throws IllegalStateException
{
switch (state.getIndex())
{
case State.STOPPED_INDEX :
{
switch (state.getIndex())
{
case State.STARTING_INDEX :
break;
case State.STOPPED_INDEX :
case State.RUNNING_INDEX :
case State.STOPPING_INDEX :
case State.FAILED_INDEX :
throw new IllegalStateException(
"Can not transition to " + newState + " state from " + state);
}
break;
}
case State.STARTING_INDEX :
{
switch (state.getIndex())
{
case State.RUNNING_INDEX :
case State.FAILED_INDEX :
case State.STOPPING_INDEX :
break;
case State.STOPPED_INDEX :
case State.STARTING_INDEX :
throw new IllegalStateException(
"Can not transition to " + newState + " state from " + state);
}
break;
}
case State.RUNNING_INDEX :
{
switch (state.getIndex())
{
case State.STOPPING_INDEX :
case State.FAILED_INDEX :
break;
case State.STOPPED_INDEX :
case State.STARTING_INDEX :
case State.RUNNING_INDEX :
throw new IllegalStateException(
"Can not transition to " + newState + " state from " + state);
} break; }
case State.STOPPING_INDEX :
{
switch (state.getIndex())
{
case State.STOPPED_INDEX :
case State.FAILED_INDEX :
break;
case State.STARTING_INDEX :
case State.RUNNING_INDEX :
case State.STOPPING_INDEX :
throw new IllegalStateException(
"Can not transition to " + newState + " state from " + state);
}
break;
}
case State.FAILED_INDEX :
{
switch (state.getIndex())
{
case State.STARTING_INDEX :
case State.STOPPING_INDEX :
break;
case State.STOPPED_INDEX :
case State.RUNNING_INDEX :
case State.FAILED_INDEX :
throw new IllegalStateException(
"Can not transition to " + newState + " state from " + state);
}
break;
}
}
log.debug("State changed from " + state + " to " + newState);
if (newState==State.RUNNING)
startTime= System.currentTimeMillis();
state= newState;
}
public long getStartTime() { return startTime;
< public void create() throws Exception {
< if (state != State.NOT_CREATED) {
< throw new IllegalStateException("Can not transition to created state from " + state);
< }
< state = State.STOPPED;
---101,105c186,249public final Container getContainer() { return container;
< public void start() throws Exception {
< if (state != State.STOPPED) {
< throw new IllegalStateException("Can not transition to started state from " + state);
< }
< state = State.STARTED;
---public final void setContainer(Container container)108,122d251
{
if (state != State.STOPPED)
{
throw new IllegalStateException(
"Set container can only be called while in the stopped state: state=" + state);
}
this.container= container;
}
public void start() throws Exception { try { setState(State.STARTING); doStart(); setState(State.RUNNING); } finally { if (state != State.RUNNING) setState(State.FAILED); } }
public void startRecursive() throws Exception { start(); }
/**
* Do the start tasks for the component. Called in the STARTING state by
* the start() and startRecursive() methods to perform the tasks required to
* start the component. The default implementation does nothing.
* @throws Exception
*/
public void doStart() throws Exception
{
}
public void stop() { // Do the actual stop tasks try { setState(State.STOPPING); doStop(); setState(State.STOPPED); } catch (Exception e) { log.warn("Stop failed", e); setState(State.FAILED); } }
/**
* Do the stop tasks for the component. Called in the STOPPING state by the stop()
* method to perform the tasks required to stop the component.
* This implementation does nothing.
* @throws Exception
*/
public void doStop() throws Exception
{
< public void stop() {
< if (state == State.NOT_CREATED || state == State.DESTROYED) {
< throw new IllegalStateException("Can not transition to started state from " + state);
< } else if (state == State.STOPPED) {
< log.warn("Stop called on an already stopped component; no exception will be thrown but this is a programming error.");
< }
< state = State.STOPPED;
< }
<
< public void destroy() {
< if (state != State.STOPPED) {
< log.warn("Destroy called on an component in the " + state + " state; no exception will be thrown but this is a programming error.");
< }
< state = State.DESTROYED;
< }
Index: modules/core/src/java/org/apache/geronimo/common/ AbstractInterceptor.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/ geronimo/common/AbstractInterceptor.java,v
retrieving revision 1.2
diff -r1.2 AbstractInterceptor.java
73,80c73,74
< if (state != State.NOT_CREATED && state != State.DESTROYED) {
< throw new IllegalStateException("setNext can only be called while in the not-created or destroyed states: state=" + state);
< }
< if (state == State.NOT_CREATED && nextInterceptor == null) {
< throw new IllegalArgumentException("Interceptor has not been created; nextInterceptor must be NOT null.");
< }
< if (state == State.DESTROYED && nextInterceptor != null) {
< throw new IllegalArgumentException("Interceptor has been destroyed; nextInterceptor must be null.");
---if (state != State.STOPPED) {Index: modules/core/src/java/org/apache/geronimo/common/Component.java
throw new IllegalStateException("setNext can only be called while in the stopped state: state=" + state);
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/ geronimo/common/Component.java,v
retrieving revision 1.2
diff -r1.2 Component.java
60c60
< *
---* Implements the JSR 77 state model71a72,77/**90,103c96
* Gets the start time of this component
* @return time in milliseonds since epoch that this component was started.
*/
long getStartTime();
< * Transitions the component to the stopped state. This method has access to the
< * container. Once an component has been created setContainer() will throw IllegalStateException.
< *
< * Normally a component uses this to acquire references to other componets of the container. The
< * components will all have been registered at this stage, but not necessarily
< * created so methods should not be invoked on the reference until the start method.
< *
< * @throws java.lang.Exception if a problem occurs during the transition
< * @throws java.lang.IllegalStateException if this interceptor is not in the not-created state
< */
< void create() throws Exception, IllegalStateException;
<
< /**
< * Transitions the component to the started state. This method has access to the
---* Transitions the component to the starting state. This method has access to the111c104
< * @throws java.lang.IllegalStateException if this interceptor is not in the stopped state
---* @throws java.lang.IllegalStateException if this interceptor is not in the stopped or failed state114a108,122/**116c124
* Transitions the component to the starting state. This method has access to the
* container.
*
* If this Component is a Container, then startRecursive is called on all child Components
* that are in the STOPPED or FAILED state.
* Normally a component uses this to cache data from other components. The other components will
* have been created at this stage, but not necessairly started and may not be ready to have methods
* invoked on them.
*
* @throws java.lang.Exception if a problem occurs during the transition
* @throws java.lang.IllegalStateException if this interceptor is not in the STOPPED or FAILED state
*/
void startRecursive() throws Exception, IllegalStateException;
< * Transitions the component to the stopped state. This method has access to the
---* Transitions the component to the stopping state. This method has access to the118a127,129* If this is Component is a Container, then all its child components must be in the
* STOPPED or FAILED State.
*123c134,136 < void stop(); ---125,135d137void stop() throws IllegalStateException;
< /**
< * Transitions the component to the destroyed state. This method has access to the
< * container. Once a component has been destroyed, it can not be recreated with the i
< * create method. If the create method is called on an destroyed component an
< * IllegalStateException will be thrown.
< *
< * Normally a component uses this to drop references to components cached in the create method.
< * The other components will not necessairly have been destroyed at this stage, but may have been
< * stopped somethods should not be called on other components.
< */
< void destroy();
Index: modules/core/src/java/org/apache/geronimo/common/State.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/ geronimo/common/State.java,v
retrieving revision 1.2
diff -r1.2 State.java
65,69c65,77
< public static final State NOT_CREATED = new State("not-created");
< public static final State STOPPED = new State("stopped");
< public static final State STARTED = new State("started");
< public static final State DESTROYED = new State("destroyed");
<
---
public static final int STARTING_INDEX=0;
public static final int RUNNING_INDEX=1;
public static final int STOPPING_INDEX=2;
public static final int STOPPED_INDEX=3;
public static final int FAILED_INDEX=4;
public static final State STARTING = new State("starting",STARTING_INDEX);
public static final State RUNNING = new State("running",RUNNING_INDEX);
public static final State STOPPING = new State("stopping",STOPPING_INDEX);
public static final State STOPPED = new State("stopped",STOPPED_INDEX);
public static final State FAILED = new State("failed",FAILED_INDEX);
71,72c79,81 < < private State(String name) { ---73a83private final int index; private State(String name, int index) {this.index = index;75a86,89Index: modules/core/src/java/org/apache/geronimo/ejb/ EJBProxyFactoryManager.javapublic int getIndex() { return index; }
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/ geronimo/ejb/EJBProxyFactoryManager.java,v
retrieving revision 1.3
diff -r1.3 EJBProxyFactoryManager.java
76,87d75
< public void create() throws Exception {
< log.debug("Creating EJBProxyFactoryManager: ejbName=" + EJBPlugins.getEJBMetadata(getContainer()).getName());
< super.create();
< for (Iterator iterator = proxies.keySet().iterator(); iterator.hasNext();) {
< String proxyName = (String) iterator.next();
< EJBProxyFactory ejbProxyFactory = getEJBProxyFactory(proxyName);
< // @todo uncomment this when the ejb proxy factories are rewriten to be full components
< //ejbProxyFactory.setContainer(getContainer());
< log.debug("Creating EJBProxyFactory: proxyName=" + proxyName + " ejbName=" + EJBPlugins.getEJBMetadata(getContainer()).getName());
< ejbProxyFactory.create();
< }
< }
89c77
< public void start() throws Exception {
---public void doStart() throws Exception {91c79,80 < super.start(); ---
// @todo This should be handled by startRecursive()100c89 < public void stop() { ---public void doStop() {102c91,92 < super.stop(); ---110a101,104
// @todo This will not work when this is a container, as children must be stopped before stop() is called.112,121d105
/**
* @todo Currently not part of the Component lifecycle (due to jsr77)
*/
< log.debug("Destroying EJBProxyFactoryManager: ejbName=" + EJBPlugins.getEJBMetadata(getContainer()).getName());
< super.destroy();
< for (Iterator iterator = proxies.keySet().iterator(); iterator.hasNext();) {
< String proxyName = (String) iterator.next();
< EJBProxyFactory ejbProxyFactory = getEJBProxyFactory(proxyName);
< log.debug("Destroying EJBProxyFactory: proxyName=" + proxyName + " ejbName=" + EJBPlugins.getEJBMetadata(getContainer()).getName());
< ejbProxyFactory.destroy();
< // @todo uncomment this when the ejb proxy factories are rewriten to be full components
< //ejbProxyFactory.setContainer(null);
< }
Index: modules/core/src/java/org/apache/geronimo/ejb/cache/ EnterpriseContextInstancePool.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/ geronimo/ejb/cache/EnterpriseContextInstancePool.java,v
retrieving revision 1.3
diff -r1.3 EnterpriseContextInstancePool.java
82,89c82,87
< public void create() throws Exception {
< super.create();
< pool = new SimpleInstancePool(EJBPlugins.getInstanceFactory(getContainer()), maxSize, hardLimit);
< discardQueue = new DiscardQueue();
< }
<
< public void start() throws Exception {
< super.start();
---public void doStart() throws Exception {92a91
if (pool==null)
pool = new SimpleInstancePool(EJBPlugins.getInstanceFactory(getContainer()), maxSize, hardLimit);
if (discardQueue==null)
discardQueue = new DiscardQueue();
// @todo Destroy not part of jsr77 lifecycle107,108d105
<
< super.destroy();
Index: modules/core/src/java/org/apache/geronimo/ejb/container/ ContainerImpl.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/ geronimo/ejb/container/ContainerImpl.java,v
retrieving revision 1.3
diff -r1.3 ContainerImpl.java
76c76,79
< *
---* @todo Currently this class implements the startRecursive method of101,109c104,118
* the JSR77 lifecycle. This should be moved to an AbstractContainer class
* @todo The stop method is implemented as stopRecursive, which is not
* supported by jsr77
< public void create() throws Exception {
< super.create();
< // Create all the interceptors in forward insertion order
< for (Iterator iterator = pluginObjects.values().iterator(); iterator.hasNext();) {
< Object object = iterator.next();
< if (object instanceof Component) {
< Component component = (Component) object;
< component.setContainer(this);
< component.create();
---111d119
public void startRecursive() throws Exception { try { // start this component setState(State.STARTING);
// Start all the components in forward insertion order
for (Iterator iterator = pluginObjects.values().iterator(); iterator.hasNext();) {
Object object = iterator.next();
if (object instanceof Component) {
Component component = (Component) object;
component.startRecursive();
}
< }
113,117c121,129
< // Create all the plugins in forward insertion order
< for (Iterator iterator = interceptors.iterator(); iterator.hasNext();) {
< Interceptor interceptor = (Interceptor) iterator.next();
< interceptor.setContainer(this);
< interceptor.create();
---120,131c132,133// Start this component doStart();
setState(State.RUNNING); } finally { if (getState() != State.RUNNING) setState(State.FAILED);
<
< public void start() throws Exception {
< super.start();
< // Start all the interceptors in forward insertion order
< for (Iterator iterator = pluginObjects.values().iterator(); iterator.hasNext();) {
< Object object = iterator.next();
< if (object instanceof Component) {
< Component component = (Component) object;
< component.start();
< }
< }
<
---140,144d141
public void doStart() throws Exception {
< // Stop all the interceptors in reverse insertion order
< for (ListIterator iterator = interceptors.listIterator(interceptors.size()); iterator.hasPrevious();) {
< Interceptor interceptor = (Interceptor) iterator.previous();
< interceptor.stop();
< }
145a143,144// @todo this is actually a stopRecursive, which is not supported158a158
// by JSR77// Stop this component160a161
162,163c163,164 < public void destroy() { < // Destroy all the interceptors in reverse insertion order ---166,181c167public void doStop() { // Stop all the interceptors in reverse insertion order
< interceptor.destroy();
< interceptor.setContainer(null);
< }
<
< // Destroy all the plugins in reverse insertion order
< LinkedList list = new LinkedList();
< for (Iterator iterator = pluginObjects.values().iterator(); iterator.hasNext();) {
< Object object = iterator.next();
< if (object instanceof Component) {
< list.addFirst(object);
< }
< }
< for (Iterator iterator = list.iterator(); iterator.hasNext();) {
< Component component = (Component) iterator.next();
< component.destroy();
< component.setContainer(null);
---interceptor.stop();182a169}183a171,173186d175// @todo destroy not supported in JSR77 lifecycle, needs to be // integrated or removed. public void destroy() {
< super.destroy();
195,199c184,185
< if (state != State.NOT_CREATED && state != State.DESTROYED) {
< throw new IllegalStateException("putPluginObject can only be called while in the not-created or destroyed states: state=" + state);
< }
< if (state == State.NOT_CREATED && objectName == null) {
< throw new IllegalArgumentException("Container has not been created; objectName must be NOT null.");
---if (state != State.STOPPED) {201,204d186
throw new IllegalStateException("putPluginObject can only be called while in the stopped state: state=" + state);
< if (state == State.DESTROYED && objectName != null) {
< throw new IllegalArgumentException("Container has been destroyed; objectName must be null.");
< }
<
214c196
< if (state != State.NOT_CREATED && state != State.DESTROYED) {
---if (state != State.STOPPED) {217,223d198
< if (state == State.NOT_CREATED && plugin == null) {
< throw new IllegalArgumentException("Container has not been created; plugin must be NOT null.");
< }
< if (state == State.DESTROYED && plugin != null) {
< throw new IllegalArgumentException("Container has been destroyed; plugin must be null.");
< }
<
Index: modules/core/src/java/org/apache/geronimo/ejb/context/ TransactionInterceptor.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/ geronimo/ejb/context/TransactionInterceptor.java,v
retrieving revision 1.3
diff -r1.3 TransactionInterceptor.java
80a81,84public long getStartTime(){ return transactionInterceptor.getStartTime(); }
97c101 < public void create() throws Exception { ---public void start() throws Exception {106,109d109 < transactionInterceptor.create(); < } < < public void start() throws Exception { 111a112,115116a121
public void startRecursive() throws Exception { transactionInterceptor.startRecursive(); }// @todo not supported by JSR77 lifecycle118d122 < transactionInterceptor.destroy();
