Author: julien(a)jboss.com
Date: 2008-02-21 18:41:05 -0500 (Thu, 21 Feb 2008)
New Revision: 10072
Added:
modules/portlet/trunk/portlet/src/test/java/org/jboss/portal/portlet/container/LifeCycleReentranceDetectionTest.java
Modified:
modules/portlet/trunk/portlet/src/main/java/org/jboss/portal/portlet/impl/container/LifeCycle.java
modules/portlet/trunk/portlet/src/test/java/org/jboss/portal/portlet/container/LifeCycle1Test.java
modules/portlet/trunk/portlet/src/test/java/org/jboss/portal/portlet/container/ObjectSupport.java
modules/portlet/trunk/portlet/src/test/resources/local-jboss-unit.xml
Log:
implement reentrancy detection + test case
Modified:
modules/portlet/trunk/portlet/src/main/java/org/jboss/portal/portlet/impl/container/LifeCycle.java
===================================================================
---
modules/portlet/trunk/portlet/src/main/java/org/jboss/portal/portlet/impl/container/LifeCycle.java 2008-02-21
22:45:43 UTC (rev 10071)
+++
modules/portlet/trunk/portlet/src/main/java/org/jboss/portal/portlet/impl/container/LifeCycle.java 2008-02-21
23:41:05 UTC (rev 10072)
@@ -44,6 +44,9 @@
/** . */
private LifeCycleStatus status = LifeCycleStatus.STOPPED;
+ /** Cheap reentrancy detection. */
+ private boolean active = false;
+
public final LifeCycleStatus getStatus()
{
return status;
@@ -51,8 +54,17 @@
private static final ThreadLocal<Set<Object>> faileds = new
ThreadLocal<Set<Object>>();
- public final void managedStart() throws IllegalStateException
+ public synchronized final void managedStart() throws IllegalStateException
{
+ if (active)
+ {
+ throw new IllegalStateException("Reentrancy detected");
+ }
+
+ //
+ active = true;
+
+ //
boolean clearFaileds = false;
//
@@ -122,36 +134,55 @@
{
faileds.set(null);
}
+
+ //
+ active = false;
}
}
- public final void managedStop()
+ public synchronized final void managedStop()
{
- stopDependents();
+ if (active)
+ {
+ throw new IllegalStateException("Reentrancy detected");
+ }
//
- if (status == LifeCycleStatus.STARTED)
+ active = true;
+
+ //
+ try
{
- try
+ stopDependents();
+
+ //
+ if (status == LifeCycleStatus.STARTED)
{
- invokeStop();
+ try
+ {
+ invokeStop();
+ }
+ catch (Exception e)
+ {
+ log.error("Error during object stop", e);
+ }
+ catch (Error e)
+ {
+ log.error("Error during object stop", e);
+ }
+ finally
+ {
+ status = LifeCycleStatus.STOPPED;
+ }
+
+ //
+ getListener().onEvent(new ManagedObjectLifeCycleEvent(this,
LifeCycleStatus.STOPPED));
}
- catch (Exception e)
- {
- log.error("Error during object stop", e);
- }
- catch (Error e)
- {
- log.error("Error during object stop", e);
- }
- finally
- {
- status = LifeCycleStatus.STOPPED;
- }
-
- //
- getListener().onEvent(new ManagedObjectLifeCycleEvent(this,
LifeCycleStatus.STOPPED));
}
+ finally
+ {
+ active = false;
+ }
}
protected void startDependents()
Modified:
modules/portlet/trunk/portlet/src/test/java/org/jboss/portal/portlet/container/LifeCycle1Test.java
===================================================================
---
modules/portlet/trunk/portlet/src/test/java/org/jboss/portal/portlet/container/LifeCycle1Test.java 2008-02-21
22:45:43 UTC (rev 10071)
+++
modules/portlet/trunk/portlet/src/test/java/org/jboss/portal/portlet/container/LifeCycle1Test.java 2008-02-21
23:41:05 UTC (rev 10072)
@@ -214,7 +214,7 @@
events.clear();
//
- container.failOnStart = true;
+ container.startCallback = ObjectSupport.FAILURE_CALLBACK;
//
applicationLC.managedStart();
@@ -281,7 +281,7 @@
events.clear();
//
- application.failOnStart = true;
+ application.startCallback = ObjectSupport.FAILURE_CALLBACK;
//
applicationLC.managedStart();
@@ -312,7 +312,7 @@
events.clear();
//
- filter.failOnStart = true;
+ filter.startCallback = ObjectSupport.FAILURE_CALLBACK;
//
applicationLC.managedStart();
@@ -371,7 +371,7 @@
@Test
public void testContainerFailsOnStop()
{
- container.failOnStop = true;
+ container.stopCallback = ObjectSupport.FAILURE_CALLBACK;
//
testApplicationLifeCycle();
@@ -380,7 +380,7 @@
@Test
public void testApplicationFailsOnStop()
{
- application.failOnStop = true;
+ application.stopCallback = ObjectSupport.FAILURE_CALLBACK;
//
testApplicationLifeCycle();
@@ -389,7 +389,7 @@
@Test
public void testFilterFailsOnStop()
{
- filter.failOnStop = true;
+ filter.stopCallback = ObjectSupport.FAILURE_CALLBACK;
//
testApplicationLifeCycle();
Added:
modules/portlet/trunk/portlet/src/test/java/org/jboss/portal/portlet/container/LifeCycleReentranceDetectionTest.java
===================================================================
---
modules/portlet/trunk/portlet/src/test/java/org/jboss/portal/portlet/container/LifeCycleReentranceDetectionTest.java
(rev 0)
+++
modules/portlet/trunk/portlet/src/test/java/org/jboss/portal/portlet/container/LifeCycleReentranceDetectionTest.java 2008-02-21
23:41:05 UTC (rev 10072)
@@ -0,0 +1,219 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2008, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.portlet.container;
+
+import org.jboss.unit.api.pojo.annotations.Test;
+import org.jboss.unit.api.pojo.annotations.Create;
+import org.jboss.portal.portlet.impl.container.PortletApplicationLifeCycle;
+import org.jboss.portal.portlet.impl.container.PortletContainerLifeCycle;
+import org.jboss.portal.portlet.impl.container.LifeCycle;
+import org.jboss.portal.portlet.container.managed.LifeCycleStatus;
+
+import static org.jboss.unit.api.Assert.*;
+
+/**
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 630 $
+ */
+@Test
+public class LifeCycleReentranceDetectionTest
+{
+
+ PortletApplicationLifeCycle applicationLF;
+ PortletApplicationObjectSupport application;
+ PortletContainerLifeCycle containerLF;
+ PortletContainerObjectSupport container;
+
+ IllegalStateException ise;
+
+ @Create
+ public void create()
+ {
+ this.ise = null;
+ }
+
+ private class InvokeLifeCycleCallback implements ObjectSupport.Callback
+ {
+
+ /** . */
+ private LifeCycle lifeCycle;
+
+ /** . */
+ private boolean invokeStart;
+
+ /** . */
+ private boolean rethrowISE;
+
+ private InvokeLifeCycleCallback(LifeCycle lifeCycle, boolean invokeStart, boolean
rethrowISE)
+ {
+ this.lifeCycle = lifeCycle;
+ this.invokeStart = invokeStart;
+ this.rethrowISE = rethrowISE;
+ }
+
+ public void execute()
+ {
+ try
+ {
+ if (invokeStart)
+ {
+ lifeCycle.managedStart();
+ }
+ else
+ {
+ lifeCycle.managedStop();
+ }
+ }
+ catch (IllegalStateException e)
+ {
+ ise = e;
+
+ //
+ if (rethrowISE)
+ {
+ throw e;
+ }
+ }
+ }
+ }
+
+ @Test
+ public void applicationReentersApplication1()
+ {
+ application = new PortletApplicationObjectSupport("application");
+ applicationLF = new PortletApplicationLifeCycle(new
PortletApplicationContextSupport(), application);
+ application.startCallback = new InvokeLifeCycleCallback(applicationLF, true,
false);
+
+ //
+ applicationLF.create();
+
+ //
+ applicationLF.managedStart();
+
+ //
+ assertNotNull(ise);
+ assertEquals(LifeCycleStatus.STARTED, applicationLF.getStatus());
+ }
+
+ @Test
+ public void applicationReentersApplication2()
+ {
+ application = new PortletApplicationObjectSupport("application");
+ applicationLF = new PortletApplicationLifeCycle(new
PortletApplicationContextSupport(), application);
+ application.startCallback = new InvokeLifeCycleCallback(applicationLF, true,
true);
+
+ //
+ applicationLF.create();
+
+ //
+ applicationLF.managedStart();
+
+ //
+ assertNotNull(ise);
+ assertEquals(LifeCycleStatus.FAILED, applicationLF.getStatus());
+ }
+
+ @Test
+ public void containerReentersContainer1()
+ {
+ application = new PortletApplicationObjectSupport("application");
+ applicationLF = new PortletApplicationLifeCycle(new
PortletApplicationContextSupport(), application);
+ container = new PortletContainerObjectSupport("container");
+ containerLF = applicationLF.addPortletContainer(new
PortletContainerContextSupport(), container);
+ container.startCallback = new InvokeLifeCycleCallback(containerLF, true, false);
+
+ //
+ applicationLF.create();
+
+ //
+ applicationLF.managedStart();
+
+ //
+ assertNotNull(ise);
+ assertEquals(LifeCycleStatus.STARTED, applicationLF.getStatus());
+ assertEquals(LifeCycleStatus.STARTED, containerLF.getStatus());
+ }
+
+ @Test
+ public void containerReentersContainer2()
+ {
+ application = new PortletApplicationObjectSupport("application");
+ applicationLF = new PortletApplicationLifeCycle(new
PortletApplicationContextSupport(), application);
+ container = new PortletContainerObjectSupport("container");
+ containerLF = applicationLF.addPortletContainer(new
PortletContainerContextSupport(), container);
+ container.startCallback = new InvokeLifeCycleCallback(containerLF, true, true);
+
+ //
+ applicationLF.create();
+
+ //
+ applicationLF.managedStart();
+
+ //
+ assertNotNull(ise);
+ assertEquals(LifeCycleStatus.STARTED, applicationLF.getStatus());
+ assertEquals(LifeCycleStatus.FAILED, containerLF.getStatus());
+ }
+
+ @Test
+ public void containerReentersApplication1()
+ {
+ application = new PortletApplicationObjectSupport("application");
+ applicationLF = new PortletApplicationLifeCycle(new
PortletApplicationContextSupport(), application);
+ container = new PortletContainerObjectSupport("container");
+ containerLF = applicationLF.addPortletContainer(new
PortletContainerContextSupport(), container);
+ container.startCallback = new InvokeLifeCycleCallback(applicationLF, true,
false);
+
+ //
+ applicationLF.create();
+
+ //
+ applicationLF.managedStart();
+
+ //
+ assertNotNull(ise);
+ assertEquals(LifeCycleStatus.STARTED, applicationLF.getStatus());
+ assertEquals(LifeCycleStatus.STARTED, containerLF.getStatus());
+ }
+
+ @Test
+ public void containerReentersApplication2()
+ {
+ application = new PortletApplicationObjectSupport("application");
+ applicationLF = new PortletApplicationLifeCycle(new
PortletApplicationContextSupport(), application);
+ container = new PortletContainerObjectSupport("container");
+ containerLF = applicationLF.addPortletContainer(new
PortletContainerContextSupport(), container);
+ container.startCallback = new InvokeLifeCycleCallback(applicationLF, true, true);
+
+ //
+ applicationLF.create();
+
+ //
+ applicationLF.managedStart();
+
+ //
+ assertNotNull(ise);
+ assertEquals(LifeCycleStatus.STARTED, applicationLF.getStatus());
+ assertEquals(LifeCycleStatus.FAILED, containerLF.getStatus());
+ }
+}
Modified:
modules/portlet/trunk/portlet/src/test/java/org/jboss/portal/portlet/container/ObjectSupport.java
===================================================================
---
modules/portlet/trunk/portlet/src/test/java/org/jboss/portal/portlet/container/ObjectSupport.java 2008-02-21
22:45:43 UTC (rev 10071)
+++
modules/portlet/trunk/portlet/src/test/java/org/jboss/portal/portlet/container/ObjectSupport.java 2008-02-21
23:41:05 UTC (rev 10072)
@@ -39,16 +39,16 @@
private int stopped;
/** . */
- boolean failOnStart;
+ Callback startCallback;
/** . */
- boolean failOnStop;
+ Callback stopCallback;
public ObjectSupport(String id)
{
this.id = id;
- this.failOnStart = false;
- this.failOnStop = false;
+ this.startCallback = null;
+ this.stopCallback = null;
}
public String getId()
@@ -71,9 +71,9 @@
started++;
//
- if (failOnStart)
+ if (startCallback != null)
{
- throw new RuntimeException();
+ startCallback.execute();
}
}
@@ -82,9 +82,22 @@
stopped++;
//
- if (failOnStop)
+ if (stopCallback != null)
{
+ stopCallback.execute();
+ }
+ }
+
+ public interface Callback
+ {
+ void execute();
+ }
+
+ public static Callback FAILURE_CALLBACK = new Callback()
+ {
+ public void execute()
+ {
throw new RuntimeException();
}
- }
+ };
}
Modified: modules/portlet/trunk/portlet/src/test/resources/local-jboss-unit.xml
===================================================================
--- modules/portlet/trunk/portlet/src/test/resources/local-jboss-unit.xml 2008-02-21
22:45:43 UTC (rev 10071)
+++ modules/portlet/trunk/portlet/src/test/resources/local-jboss-unit.xml 2008-02-21
23:41:05 UTC (rev 10072)
@@ -4,7 +4,6 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:jboss:jboss-unit:1.0 jboss-unit_1_0.xsd">
<pojo>
-<!--
<test>
<class
name="org.jboss.portal.test.portlet.state.LocalStoreProducerStatefulPortletInvokerTestCase"/>
</test>
@@ -38,9 +37,11 @@
<test>
<class
name="org.jboss.portal.test.portlet.StateStringTestCase"/>
</test>
--->
<test>
<class
name="org.jboss.portal.portlet.container.LifeCycle1Test"/>
</test>
+ <test>
+ <class
name="org.jboss.portal.portlet.container.LifeCycleReentranceDetectionTest"/>
+ </test>
</pojo>
</jboss-unit>