[jboss-cvs] JBossAS SVN: r76006 - in projects/ejb3/trunk: core/src/main/java/org/jboss/ejb3/mdb and 6 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri Jul 18 18:37:00 EDT 2008
Author: pferraro
Date: 2008-07-18 18:37:00 -0400 (Fri, 18 Jul 2008)
New Revision: 76006
Added:
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/BlockContainerShutdownInterceptor.java
Modified:
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/ConsumerContainer.java
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MDB.java
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/service/ServiceContainer.java
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionContainer.java
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/stateful/StatefulContainer.java
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java
projects/ejb3/trunk/core/src/main/resources/ejb3-interceptors-aop.xml
projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/ejbthree1116/unit/ContainerShutdownTestCase.java
Log:
[EJBTHREE-1116] Clustered container sees requests during shutdown.
Leverage read-write lock to support clean startup/shutdown of an EJBContainer.
Write lock is acquired on create(), released after start(), and re-acquired on stop().
Read locks are acquired/released via interceptor early in the chain.
Added: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/BlockContainerShutdownInterceptor.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/BlockContainerShutdownInterceptor.java (rev 0)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/BlockContainerShutdownInterceptor.java 2008-07-18 22:37:00 UTC (rev 76006)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.ejb3;
+
+import java.io.Serializable;
+import java.util.concurrent.locks.Lock;
+
+import org.jboss.aop.DispatcherConnectException;
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.joinpoint.Invocation;
+
+/**
+ * An interceptor that blocks container shutdown until the interceptor chain completes
+ * and rejects invocations if container is not completely started or is stopped.
+ *
+ * @author Paul Ferraro
+ */
+public class BlockContainerShutdownInterceptor implements Interceptor, Serializable
+{
+ private static final long serialVersionUID = -1683253088746668495L;
+
+ /**
+ * @see org.jboss.aop.advice.Interceptor#getName()
+ */
+ public String getName()
+ {
+ return this.getClass().getName();
+ }
+
+ /**
+ * @see org.jboss.aop.advice.Interceptor#invoke(org.jboss.aop.joinpoint.Invocation)
+ */
+ public Object invoke(Invocation invocation) throws Throwable
+ {
+ EJBContainer container = EJBContainer.getEJBContainer(invocation.getAdvisor());
+
+ Lock lock = container.getInvocationLock();
+
+ if (!lock.tryLock())
+ {
+ throw new DispatcherConnectException("EJB container is not completely started, or is stopped.");
+ }
+
+ try
+ {
+ return invocation.invokeNext();
+ }
+ finally
+ {
+ lock.unlock();
+ }
+ }
+}
Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java 2008-07-18 21:11:21 UTC (rev 76005)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java 2008-07-18 22:37:00 UTC (rev 76006)
@@ -35,6 +35,9 @@
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@@ -181,6 +184,9 @@
protected boolean reinitialize = false;
+ // To support clean startup/shutdown
+ private ReadWriteLock containerLock = new ReentrantReadWriteLock();
+
/**
* @param name Advisor name
* @param manager Domain to get interceptor bindings from
@@ -829,6 +835,8 @@
public void create() throws Exception
{
+ // Lock until start()
+ this.getContainerLock().lock();
/*
initializeClassContainer();
for (int i = 0; i < constructors.length; i++)
@@ -842,8 +850,15 @@
*/
}
+ public final void start() throws Exception
+ {
+ this.lockedStart();
+
+ this.getContainerLock().unlock();
+ }
+
// Everything must be done in start to make sure all dependencies have been satisfied
- public void start() throws Exception
+ protected void lockedStart() throws Exception
{
if (reinitialize)
reinitialize();
@@ -870,8 +885,15 @@
log.info("STARTED EJB: " + beanClass.getName() + " ejbName: " + ejbName);
}
- public void stop() throws Exception
+ public final void stop() throws Exception
{
+ this.getContainerLock().lockInterruptibly();
+
+ this.lockedStop();
+ }
+
+ protected void lockedStop() throws Exception
+ {
reinitialize = true;
//encFactory.cleanupEnc(this);
@@ -1500,6 +1522,16 @@
return bridgeMethod;
}
+ public Lock getInvocationLock()
+ {
+ return this.containerLock.readLock();
+ }
+
+ private Lock getContainerLock()
+ {
+ return this.containerLock.writeLock();
+ }
+
public String toString()
{
return getObjectName().getCanonicalName();
Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/ConsumerContainer.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/ConsumerContainer.java 2008-07-18 21:11:21 UTC (rev 76005)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/ConsumerContainer.java 2008-07-18 22:37:00 UTC (rev 76006)
@@ -252,9 +252,10 @@
*
* @throws Exception Failed to initalize.
*/
- public void start() throws Exception
+ @Override
+ protected void lockedStart() throws Exception
{
- super.start();
+ super.lockedStart();
registerProducers();
}
@@ -301,9 +302,10 @@
activationSpec.merge(md.activationConfig());
}
- public void stop() throws Exception
+ @Override
+ protected void lockedStop() throws Exception
{
unregisterProducers();
- super.stop();
+ super.lockedStop();
}
}
Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MDB.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MDB.java 2008-07-18 21:11:21 UTC (rev 76005)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MDB.java 2008-07-18 22:37:00 UTC (rev 76006)
@@ -132,11 +132,6 @@
list.add(getMessagingType());
return list;
}
-
- public void start() throws Exception
- {
- super.start();
- }
public ObjectName getJmxName()
{
Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java 2008-07-18 21:11:21 UTC (rev 76005)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java 2008-07-18 22:37:00 UTC (rev 76006)
@@ -159,9 +159,10 @@
*
* @throws Exception Failed to initalize.
*/
- public void start() throws Exception
+ @Override
+ protected void lockedStart() throws Exception
{
- super.start();
+ super.lockedStart();
populateActivationSpec();
@@ -293,8 +294,8 @@
}
}
-
- public void stop() throws Exception
+ @Override
+ protected void lockedStop() throws Exception
{
if (timerService != null)
{
@@ -304,7 +305,7 @@
stopProxies();
- super.stop();
+ super.lockedStop();
}
protected void stopProxies() throws Exception
Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/service/ServiceContainer.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/service/ServiceContainer.java 2008-07-18 21:11:21 UTC (rev 76005)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/service/ServiceContainer.java 2008-07-18 22:37:00 UTC (rev 76006)
@@ -203,9 +203,10 @@
invokeOptionalMethod("create");
}
- public void start() throws Exception
+ @Override
+ protected void lockedStart() throws Exception
{
- super.start();
+ super.lockedStart();
try
{
@@ -226,11 +227,12 @@
catch (Exception e)
{
e.printStackTrace();
- stop();
+ this.lockedStop();
}
}
- public void stop() throws Exception
+ @Override
+ protected void lockedStop() throws Exception
{
invokeOptionalMethod("stop");
@@ -246,7 +248,7 @@
singleton = null;
beanContext = null;
- super.stop();
+ super.lockedStop();
}
public void destroy() throws Exception
Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionContainer.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionContainer.java 2008-07-18 21:11:21 UTC (rev 76005)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionContainer.java 2008-07-18 22:37:00 UTC (rev 76006)
@@ -180,9 +180,9 @@
return list;
}
- public void start() throws Exception
+ protected void lockedStart() throws Exception
{
- super.start();
+ super.lockedStart();
// So that Remoting layer can reference this container easily.
Dispatcher.singleton.registerTarget(getObjectName().getCanonicalName(), new ClassProxyHack(this));
proxyDeployer.start();
@@ -208,7 +208,7 @@
return clusterFamilies;
}
- public void stop() throws Exception
+ protected void lockedStop() throws Exception
{
try
{
@@ -226,7 +226,7 @@
{
log.debug("Dispatcher unregister target failed", ignore);
}
- super.stop();
+ super.lockedStop();
}
@Override
Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/stateful/StatefulContainer.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/stateful/StatefulContainer.java 2008-07-18 21:11:21 UTC (rev 76005)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/stateful/StatefulContainer.java 2008-07-18 22:37:00 UTC (rev 76006)
@@ -278,18 +278,19 @@
this.cache.start();
}
- public void start() throws Exception
+ @Override
+ protected void lockedStart() throws Exception
{
try
{
- super.start();
+ super.lockedStart();
this.createAndStartCache();
}
catch (Exception e)
{
try
{
- stop();
+ this.lockedStop();
}
catch (Exception ignore)
{
@@ -300,10 +301,12 @@
}
- public void stop() throws Exception
+ @Override
+ protected void lockedStop() throws Exception
{
- super.stop();
if (cache != null) cache.stop();
+
+ super.lockedStop();
}
public StatefulCache getCache()
Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java 2008-07-18 21:11:21 UTC (rev 76005)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java 2008-07-18 22:37:00 UTC (rev 76006)
@@ -195,11 +195,12 @@
this.timeout = getTimeoutCallback(timeoutMethodMetaData, getBeanClass());
}
- public void start() throws Exception
+ @Override
+ protected void lockedStart() throws Exception
{
try
{
- super.start();
+ super.lockedStart();
timerService = TimerServiceFactory.getInstance().createTimerService(this, this);
@@ -209,7 +210,7 @@
{
try
{
- stop();
+ this.lockedStop();
}
catch (Exception ignore)
{
@@ -219,7 +220,8 @@
}
}
- public void stop() throws Exception
+ @Override
+ protected void lockedStop() throws Exception
{
if (timerService != null)
{
@@ -227,7 +229,7 @@
timerService = null;
}
- super.stop();
+ super.lockedStop();
}
public TimerService getTimerService()
Modified: projects/ejb3/trunk/core/src/main/resources/ejb3-interceptors-aop.xml
===================================================================
--- projects/ejb3/trunk/core/src/main/resources/ejb3-interceptors-aop.xml 2008-07-18 21:11:21 UTC (rev 76005)
+++ projects/ejb3/trunk/core/src/main/resources/ejb3-interceptors-aop.xml 2008-07-18 22:37:00 UTC (rev 76006)
@@ -82,6 +82,7 @@
<interceptor class="org.jboss.ejb3.AllowedOperationsInterceptor" scope="PER_VM"/>
<interceptor factory="org.jboss.ejb3.mdb.CurrentMessageInjectorInterceptorFactory" scope="PER_CLASS"/>
<interceptor class="org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor" scope="PER_VM"/>
+ <interceptor class="org.jboss.ejb3.BlockContainerShutdownInterceptor" scope="PER_VM"/>
<!--
INTERCEPTORS
@@ -140,6 +141,7 @@
<bind pointcut="execution(public * *->*(..))">
<interceptor-ref name="org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor"/>
+ <interceptor-ref name="org.jboss.ejb3.BlockContainerShutdownInterceptor"/>
</bind>
</domain>
Modified: projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/ejbthree1116/unit/ContainerShutdownTestCase.java
===================================================================
--- projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/ejbthree1116/unit/ContainerShutdownTestCase.java 2008-07-18 21:11:21 UTC (rev 76005)
+++ projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/ejbthree1116/unit/ContainerShutdownTestCase.java 2008-07-18 22:37:00 UTC (rev 76006)
@@ -54,6 +54,8 @@
{
MyStateful bean = (MyStateful) new InitialContext().lookup("MyStatefulBean/remote");
+ bean.increment();
+
this.undeploy(JAR);
try
@@ -80,10 +82,33 @@
{
MyStateful bean = (MyStateful) new InitialContext().lookup("MyStatefulBean/remote");
- CountDownLatch latch = new CountDownLatch(2);
+ bean.increment();
- Thread thread = new Thread(new Undeployer(latch));
+ final CountDownLatch latch = new CountDownLatch(2);
+ Thread thread = new Thread()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ latch.countDown();
+ latch.await();
+
+ ContainerShutdownTestCase.this.undeploy(JAR);
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ catch (Exception e)
+ {
+ ContainerShutdownTestCase.this.log.error(e.getMessage(), e);
+ }
+ }
+ };
+
thread.start();
latch.countDown();
@@ -125,36 +150,7 @@
}
}
}
-
- private class Undeployer implements Runnable
- {
- private CountDownLatch latch;
-
- public Undeployer(CountDownLatch latch)
- {
- this.latch = latch;
- }
-
- public void run()
- {
- try
- {
- this.latch.countDown();
- this.latch.await();
- ContainerShutdownTestCase.this.undeploy(JAR);
- }
- catch (InterruptedException e)
- {
- Thread.currentThread().interrupt();
- }
- catch (Exception e)
- {
- ContainerShutdownTestCase.this.log.error(e.getMessage(), e);
- }
- }
- }
-
public static Test suite() throws Exception
{
return getDeploySetup(ContainerShutdownTestCase.class, JAR);
More information about the jboss-cvs-commits
mailing list