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() {
---
    public State getState()
    {
77,91c79,178
< 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;
---
/**
* 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;
94,98c181,183
< public void create() throws Exception {
< if (state != State.NOT_CREATED) {
< throw new IllegalStateException("Can not transition to created state from " + state);
< }
< state = State.STOPPED;
---
    public final Container getContainer()
    {
        return container;
101,105c186,249
< 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)
{
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
{
108,122d251
< 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) {
throw new IllegalStateException("setNext can only be called while in the stopped state: state=" + state);
Index: modules/core/src/java/org/apache/geronimo/common/Component.java
===================================================================
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 model
71a72,77
/**
* Gets the start time of this component
* @return time in milliseonds since epoch that this component was started.
*/
long getStartTime();
90,103c96
< * 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 the
111c104
< * @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 state
114a108,122
/**
* 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;


116c124
< * 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 the
118a127,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();
---
    void stop() throws IllegalStateException;


125,135d137
< /**
< * 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) {
---
        private final int index;
        
    private State(String name, int index) {
73a83
this.index = index;
75a86,89
        public int getIndex() { 
                return index;
        }
        
Index: modules/core/src/java/org/apache/geronimo/ejb/ EJBProxyFactoryManager.java
===================================================================
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();
---

// @todo This will not work when this is a container, as children must be stopped before stop() is called.
110a101,104

/**
* @todo Currently not part of the Component lifecycle (due to jsr77)
*/
112,121d105
< 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 {
if (pool==null)
pool = new SimpleInstancePool(EJBPlugins.getInstanceFactory(getContainer()), maxSize, hardLimit);
if (discardQueue==null)
discardQueue = new DiscardQueue();


92a91
// @todo Destroy not part of jsr77 lifecycle
107,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 of
* 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
101,109c104,118
< 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();
---

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();
}
111d119
< }
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();
---
            // Start this component
            doStart();

            setState(State.RUNNING);
        }
        finally
        {
            if (getState() != State.RUNNING)
                setState(State.FAILED);
120,131c132,133
<
< 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();
< }
< }
<
---

public void doStart() throws Exception {
140,144d141
< // 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 supported
// by JSR77
158a158
// Stop this component
160a161

162,163c163,164
<     public void destroy() {
<         // Destroy all the interceptors in reverse insertion order
---
    public void doStop() {
        // Stop all the interceptors in reverse insertion order
166,181c167
< 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,173
    // @todo destroy not supported in JSR77 lifecycle, needs to be
    // integrated or removed.
    public void destroy() {
186d175
< 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) {
throw new IllegalStateException("putPluginObject can only be called while in the stopped state: state=" + state);
201,204d186
< 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,84
    public 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,115

public void startRecursive() throws Exception { transactionInterceptor.startRecursive(); }
116a121
// @todo not supported by JSR77 lifecycle
118d122
<         transactionInterceptor.destroy();



Reply via email to