Index: as-int/pom.xml =================================================================== --- as-int/pom.xml (revision 83558) +++ as-int/pom.xml (working copy) @@ -28,7 +28,7 @@ into the AS --> - 1.0.1-SNAPSHOT + 1.1.0-SNAPSHOT 1.0.0 1.0.0 @@ -63,6 +63,12 @@ jboss-ejb3-mc-int ${version.org.jboss.ejb3_mc.int} + + + org.jboss.ejb3 + jboss-ejb3-timerservice-as5 + 0.1.0-SNAPSHOT + Index: core/src/test/java/org/jboss/ejb3/core/test/common/AbstractEJB3TestCase.java =================================================================== --- core/src/test/java/org/jboss/ejb3/core/test/common/AbstractEJB3TestCase.java (revision 83558) +++ core/src/test/java/org/jboss/ejb3/core/test/common/AbstractEJB3TestCase.java (working copy) @@ -135,6 +135,7 @@ deploy("namingserver-beans.xml"); deploy("transactionmanager-beans.xml"); + deploy("mocktimerservice-beans.xml"); deploy("servicecontainer-beans.xml"); deploy("statefulcontainer-beans.xml"); deploy("statelesscontainer-beans.xml"); Index: core/src/main/java/org/jboss/ejb3/service/ServiceContainer.java =================================================================== --- core/src/main/java/org/jboss/ejb3/service/ServiceContainer.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/service/ServiceContainer.java (working copy) @@ -53,6 +53,7 @@ import org.jboss.aop.util.MethodHashing; import org.jboss.aop.util.PayloadKey; import org.jboss.aspects.asynch.FutureHolder; +import org.jboss.beans.metadata.api.annotations.Inject; import org.jboss.ejb.AllowedOperationsAssociation; import org.jboss.ejb.AllowedOperationsFlags; import org.jboss.ejb3.BeanContext; @@ -73,8 +74,8 @@ import org.jboss.ejb3.proxy.objectstore.ObjectStoreBindings; import org.jboss.ejb3.session.SessionContainer; import org.jboss.ejb3.stateful.StatefulContainerInvocation; -import org.jboss.ejb3.timerservice.TimedObjectInvoker; -import org.jboss.ejb3.timerservice.TimerServiceFactory; +import org.jboss.ejb3.timerservice.spi.TimedObjectInvoker; +import org.jboss.ejb3.timerservice.spi.TimerServiceFactory; import org.jboss.injection.Injector; import org.jboss.logging.Logger; import org.jboss.metadata.ejb.jboss.JBossServiceBeanMetaData; @@ -105,6 +106,8 @@ private Method timeoutMethod; + private TimerServiceFactory timerServiceFactory; + @SuppressWarnings("unused") private static final Logger log = Logger.getLogger(ServiceContainer.class); @@ -303,11 +306,11 @@ initBeanContext(); // make sure the timer service is there before injection takes place - timerService = TimerServiceFactory.getInstance().createTimerService(this, this); + timerService = timerServiceFactory.createTimerService(this); injectDependencies(beanContext); - TimerServiceFactory.getInstance().restoreTimerService(timerService); + timerServiceFactory.restoreTimerService(timerService); invokeOptionalMethod(METHOD_NAME_LIFECYCLE_CALLBACK_START); } catch (Exception e) @@ -333,7 +336,7 @@ if (timerService != null) { - TimerServiceFactory.getInstance().removeTimerService(timerService); + timerServiceFactory.suspendTimerService(timerService); timerService = null; } @@ -690,6 +693,14 @@ throw new NotImplementedException(this + " is no longer using unsupported (legacy) proxy impl from ejb3-core"); } + /* (non-Javadoc) + * @see org.jboss.ejb3.timerservice.spi.TimedObjectInvoker#getTimedObjectId() + */ + public String getTimedObjectId() + { + return getDeploymentQualifiedName(); + } + private void registerManagementInterface() { try @@ -838,4 +849,10 @@ { throw new RuntimeException("Don't do this"); } + + @Inject + public void setTimerServiceFactory(TimerServiceFactory factory) + { + this.timerServiceFactory = factory; + } } Index: core/src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java =================================================================== --- core/src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java (working copy) @@ -46,6 +46,7 @@ import org.jboss.aop.joinpoint.InvocationResponse; import org.jboss.aop.joinpoint.MethodInvocation; import org.jboss.aspects.asynch.FutureHolder; +import org.jboss.beans.metadata.api.annotations.Inject; import org.jboss.ejb.AllowedOperationsAssociation; import org.jboss.ejb.AllowedOperationsFlags; import org.jboss.ejb3.BeanContext; @@ -77,8 +78,8 @@ import org.jboss.ejb3.proxy.remoting.SessionSpecRemotingMetadata; import org.jboss.ejb3.session.SessionContainer; import org.jboss.ejb3.session.SessionSpecContainer; -import org.jboss.ejb3.timerservice.TimedObjectInvoker; -import org.jboss.ejb3.timerservice.TimerServiceFactory; +import org.jboss.ejb3.timerservice.spi.TimedObjectInvoker; +import org.jboss.ejb3.timerservice.spi.TimerServiceFactory; import org.jboss.ejb3.util.CollectionHelper; import org.jboss.injection.WebServiceContextProxy; import org.jboss.injection.lang.reflect.BeanProperty; @@ -110,6 +111,8 @@ private Method timeout; private StatelessDelegateWrapper mbean = new StatelessDelegateWrapper(this); + private TimerServiceFactory timerServiceFactory; + public StatelessContainer(ClassLoader cl, String beanClassName, String ejbName, Domain domain, Hashtable ctxProperties, Ejb3Deployment deployment, JBossSessionBeanMetaData beanMetaData) throws ClassNotFoundException { @@ -246,9 +249,9 @@ { super.lockedStart(); - timerService = TimerServiceFactory.getInstance().createTimerService(this, this); + timerService = timerServiceFactory.createTimerService(this); - TimerServiceFactory.getInstance().restoreTimerService(timerService); + timerServiceFactory.restoreTimerService(timerService); } catch (Exception e) { @@ -269,7 +272,7 @@ { if (timerService != null) { - TimerServiceFactory.getInstance().removeTimerService(timerService); + timerServiceFactory.suspendTimerService(timerService); timerService = null; } @@ -744,6 +747,20 @@ : ObjectStoreBindings.OBJECTSTORE_BEAN_NAME_JNDI_REGISTRAR_SLSB; } + /* (non-Javadoc) + * @see org.jboss.ejb3.timerservice.spi.TimedObjectInvoker#getTimedObjectId() + */ + public String getTimedObjectId() + { + return getDeploymentQualifiedName(); + } + + @Inject + public void setTimerServiceFactory(TimerServiceFactory factory) + { + this.timerServiceFactory = factory; + } + static class WSCallbackImpl implements BeanContextLifecycleCallback { private ExtensibleWebServiceContext jaxwsContext; Index: core/src/main/java/org/jboss/ejb3/timerservice/jboss/TimerServiceFacade.java =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/jboss/TimerServiceFacade.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/jboss/TimerServiceFacade.java (working copy) @@ -1,104 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, 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.timerservice.jboss; - -import static org.jboss.ejb.AllowedOperationsFlags.IN_BUSINESS_METHOD; -import static org.jboss.ejb.AllowedOperationsFlags.IN_EJB_TIMEOUT; -import static org.jboss.ejb.AllowedOperationsFlags.IN_SERVICE_ENDPOINT_METHOD; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Date; - -import javax.ejb.EJBException; -import javax.ejb.Timer; -import javax.ejb.TimerService; -import javax.management.ObjectName; - -import org.jboss.ejb.AllowedOperationsAssociation; -import org.jboss.ejb3.Container; -import org.jboss.ejb3.EJBContainer; - -/** - * Holds the association with the container, without exposing it. - * - * @author Carlo de Wolf - * @version $Revision: $ - */ -public class TimerServiceFacade implements TimerService -{ - private TimerService delegate; - - private Container container; - - protected TimerServiceFacade(Container container, TimerService delegate) - { - this.container = container; - this.delegate = delegate; - } - - private void assertAllowedIn(String timerMethod) - { - // TODO: This isn't handled by the AS timer service itself - AllowedOperationsAssociation.assertAllowedIn(timerMethod, IN_BUSINESS_METHOD | IN_EJB_TIMEOUT | IN_SERVICE_ENDPOINT_METHOD); - } - - public Timer createTimer(Date initialExpiration, long intervalDuration, Serializable info) throws IllegalArgumentException, IllegalStateException, EJBException - { - assertAllowedIn("TimerService.createTimer"); - return delegate.createTimer(initialExpiration, intervalDuration, info); - } - - public Timer createTimer(Date expiration, Serializable info) throws IllegalArgumentException, IllegalStateException, EJBException - { - assertAllowedIn("TimerService.createTimer"); - return delegate.createTimer(expiration, info); - } - - public Timer createTimer(long initialDuration, long intervalDuration, Serializable info) throws IllegalArgumentException, IllegalStateException, EJBException - { - assertAllowedIn("TimerService.createTimer"); - return delegate.createTimer(initialDuration, intervalDuration, info); - } - - public Timer createTimer(long duration, Serializable info) throws IllegalArgumentException, IllegalStateException, EJBException - { - assertAllowedIn("TimerService.createTimer"); - return delegate.createTimer(duration, info); - } - - protected EJBContainer getContainer() - { - return (EJBContainer) container; - } - - protected ObjectName getContainerId() - { - return container.getObjectName(); - } - - public Collection getTimers() throws IllegalStateException, EJBException - { - assertAllowedIn("TimerService.getTimers"); - return delegate.getTimers(); - } -} Index: core/src/main/java/org/jboss/ejb3/timerservice/jboss/JBossTimerServiceFactory.java =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/jboss/JBossTimerServiceFactory.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/jboss/JBossTimerServiceFactory.java (working copy) @@ -1,135 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, 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.timerservice.jboss; - -import javax.ejb.TimerService; -import javax.management.ObjectName; - -import org.jboss.ejb.AllowedOperationsAssociation; -import org.jboss.ejb.txtimer.EJBTimerService; -import org.jboss.ejb3.Container; -import org.jboss.ejb3.EJBContainer; -import org.jboss.ejb3.timerservice.TimedObjectInvoker; -import org.jboss.ejb3.timerservice.TimerServiceFactory; -import org.jboss.logging.Logger; -import org.jboss.mx.util.MBeanProxyExt; -import org.jboss.mx.util.MBeanServerLocator; - -/** - * Factory to create timer services which use the JBoss EJB Timer Service. - * - * @author Carlo de Wolf - * @version $Revision: $ - */ -public class JBossTimerServiceFactory extends TimerServiceFactory -{ - private static Logger log = Logger.getLogger(JBossTimerServiceFactory.class); - - /* (non-Javadoc) - * @see org.jboss.ejb3.timerservice.TimerServiceFactory#createTimerService(javax.management.ObjectName, org.jboss.ejb3.timerservice.TimedObjectInvoker) - */ - @Override - public TimerService createTimerService(Container container, TimedObjectInvoker invoker) - { - TimerService timerService = null; - try - { - EJBTimerService service = getEJBTimerService(); - TimerService delegate = service.createTimerService(container.getObjectName(), null, invoker); - timerService = new TimerServiceFacade(container, delegate); - } - catch (Exception e) - { - //throw new EJBException("Could not create timer service", e); - if (log.isTraceEnabled()) - { - log.trace("Unable to initialize timer service", e); - } - else - { - log.trace("Unable to initialize timer service"); - } - } - return timerService; - } - - protected EJBTimerService getEJBTimerService() - { - return (EJBTimerService) MBeanProxyExt.create(EJBTimerService.class, EJBTimerService.OBJECT_NAME, MBeanServerLocator.locateJBoss()); - } - - /* (non-Javadoc) - * @see org.jboss.ejb3.timerservice.TimerServiceFactory#removeTimerService(javax.ejb.TimerService) - */ - @Override - public void removeTimerService(TimerService timerService) - { - removeTimerService(((TimerServiceFacade) timerService).getContainerId()); - } - - protected void removeTimerService(ObjectName containerId) - { - try - { - EJBTimerService service = getEJBTimerService(); - service.removeTimerService(containerId, true); - } - catch (Exception e) - { - //throw new EJBException("Could not remove timer service", e); - if (log.isTraceEnabled()) - { - log.trace("Unable to initialize timer service", e); - } - else - { - log.trace("Unable to initialize timer service"); - } - } - } - - public void restoreTimerService(TimerService aTimerService) - { - if (aTimerService == null) - { - log.warn("TIMER SERVICE IS NOT INSTALLED"); - return; - } - TimerServiceFacade timerService = (TimerServiceFacade) aTimerService; - EJBContainer container = timerService.getContainer(); - // FIXME: do not assume that a TimedObjectInvoker is an EJBContainer - ClassLoader loader = container.getClassloader(); - - // FIXME: A hack to circumvent the check in TimerServiceFacade - // In AS itself (/EJB2) the container has an unsecured timer service association - // see org.jboss.ejb.Container.getTimerService(Object pKey) - AllowedOperationsAssociation.pushInMethodFlag(AllowedOperationsAssociation.IN_BUSINESS_METHOD); - try - { - getEJBTimerService().restoreTimers(timerService.getContainerId(), loader); - } - finally - { - AllowedOperationsAssociation.popInMethodFlag(); - } - } -} Index: core/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerServiceFactory.java =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerServiceFactory.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerServiceFactory.java (working copy) @@ -1,275 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, 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.timerservice.quartz; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Properties; - -import javax.ejb.TimerService; -import javax.management.ObjectName; -import javax.naming.InitialContext; -import javax.transaction.HeuristicMixedException; -import javax.transaction.HeuristicRollbackException; -import javax.transaction.NotSupportedException; -import javax.transaction.RollbackException; -import javax.transaction.Status; -import javax.transaction.SystemException; -import javax.transaction.TransactionManager; - -import org.jboss.ejb3.Container; -import org.jboss.ejb3.InitialContextFactory; -import org.jboss.ejb3.timerservice.TimedObjectInvoker; -import org.jboss.ejb3.timerservice.TimerServiceFactory; -import org.jboss.logging.Logger; -import org.quartz.Scheduler; -import org.quartz.SchedulerFactory; -import org.quartz.impl.StdSchedulerFactory; -import org.quartz.utils.DBConnectionManager; -import org.quartz.utils.JNDIConnectionProvider; - -/** - * Creates timer service objects for use in EJB3 containers. For this - * two methods are provided: createTimerService and removeTimerService. - * - * The factory can be started and stopped within both an embedded and full stack. - * - * For now only one scheduler is supported. Each bean container has its own - * job and trigger group within Quartz. - * - * @author Carlo de Wolf - * @version $Revision: 56116 $ - */ -public class QuartzTimerServiceFactory extends TimerServiceFactory -{ - @SuppressWarnings("unused") - private static final Logger log = Logger.getLogger(QuartzTimerServiceFactory.class); - - private TransactionManager tm; - - private static Scheduler scheduler; - - private Properties properties; - - /** - * Contains the sql statements to create the database schema. - */ - private Properties sqlProperties; - - private void createSchema() - { - try - { - tm.begin(); - try - { - Connection conn = getConnection(); - try - { - boolean success = execute(conn, "CREATE_TABLE_JOB_DETAILS"); - if(success) - { - execute(conn, "CREATE_TABLE_JOB_LISTENERS"); - execute(conn, "CREATE_TABLE_TRIGGERS"); - execute(conn, "CREATE_TABLE_SIMPLE_TRIGGERS"); - execute(conn, "CREATE_TABLE_CRON_TRIGGERS"); - execute(conn, "CREATE_TABLE_BLOB_TRIGGERS"); - execute(conn, "CREATE_TABLE_TRIGGER_LISTENERS"); - execute(conn, "CREATE_TABLE_CALENDARS"); - execute(conn, "CREATE_TABLE_PAUSED_TRIGGER_GRPS"); - execute(conn, "CREATE_TABLE_FIRED_TRIGGERS"); - execute(conn, "CREATE_TABLE_SCHEDULER_STATE"); - execute(conn, "CREATE_TABLE_LOCKS"); - - execute(conn, "INSERT_TRIGGER_ACCESS"); - execute(conn, "INSERT_JOB_ACCESS"); - execute(conn, "INSERT_CALENDAR_ACCESS"); - execute(conn, "INSERT_STATE_ACCESS"); - execute(conn, "INSERT_MISFIRE_ACCESS"); - } - } - finally - { - conn.close(); - } - tm.commit(); - } - catch(SQLException e) - { - throw new RuntimeException(e); - } - catch (RollbackException e) - { - throw new RuntimeException(e); - } - catch (HeuristicMixedException e) - { - throw new RuntimeException(e); - } - catch (HeuristicRollbackException e) - { - throw new RuntimeException(e); - } - finally - { - if(tm.getStatus() == Status.STATUS_ACTIVE) - tm.rollback(); - } - } - catch(SystemException e) - { - throw new RuntimeException(e); - } - catch (NotSupportedException e) - { - throw new RuntimeException(e); - } - } - - /** - * Create a TimerService for use in a bean container. - * - * @param objectName the name of the bean container - * @param invoker the invoker to call on timeouts - * @return an EJB TimerService - */ - public TimerService createTimerService(Container container, TimedObjectInvoker invoker) - { - Scheduler scheduler = getScheduler(); - if (scheduler == null) return null; - - return new TimerServiceImpl(scheduler, container, invoker); - } - - private boolean execute(Connection conn, String stmtName) throws SQLException - { - String sql = sqlProperties.getProperty(stmtName); - if(sql == null) - throw new IllegalStateException("No sql set for '" + stmtName + "'"); - - PreparedStatement stmt = conn.prepareStatement(sql); - try - { - stmt.execute(); - return true; - } - catch(SQLException e) - { - log.warn("sql failed: " + sql); - if(log.isDebugEnabled()) - log.debug("sql failed: " + sql, e); - return false; - } - finally - { - stmt.close(); - } - } - - private Connection getConnection() throws SQLException - { - return DBConnectionManager.getInstance().getConnection("myDS"); - } - - /** - * @return the scheduler for package use - */ - protected static Scheduler getScheduler() - { - if(scheduler == null) - { - return null; - //throw new IllegalStateException("TimerServiceFactory hasn't been started yet"); - } - - return scheduler; - } - - public void removeTimerService(TimerService aTimerService) - { - TimerServiceImpl timerService = (TimerServiceImpl) aTimerService; - timerService.shutdown(); - } - - public void restoreTimerService(TimerService aTimerService) - { - // TODO: implement Quartz restore timer service - } - - public void setDataSource(String jndiName) - { - JNDIConnectionProvider connectionProvider = new JNDIConnectionProvider(jndiName, false); - // FIXME: remove hardcoding - DBConnectionManager.getInstance().addConnectionProvider("myDS", connectionProvider); - } - - public void setProperties(final Properties props) - { -// if(scheduler != null) -// throw new IllegalStateException("already started"); - - // TODO: precondition the prop - properties = props; - } - - public void setSqlProperties(Properties props) - { - this.sqlProperties = props; - } - - public synchronized void start() throws Exception - { - if(scheduler != null) - throw new IllegalStateException("already started"); - - log.debug("properties = " + properties); - - InitialContext ctx = InitialContextFactory.getInitialContext(); - tm = (TransactionManager) ctx.lookup("java:/TransactionManager"); - - createSchema(); - - // TODO: bind in JNDI, or is this done by the JMX bean? - SchedulerFactory factory; - if(properties == null) - factory = new StdSchedulerFactory(); - else - factory = new StdSchedulerFactory(properties); - scheduler = factory.getScheduler(); - // TODO: really start right away? - scheduler.start(); - } - - public synchronized void stop() throws Exception - { - if(scheduler == null) - throw new IllegalStateException("already stopped"); - - // TODO: unbind from JNDI - - // TODO: standby or shutdown? - scheduler.shutdown(); - - scheduler = null; - } -} Index: core/src/main/java/org/jboss/ejb3/timerservice/quartz/PersistentTimer.java =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/quartz/PersistentTimer.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/quartz/PersistentTimer.java (working copy) @@ -1,96 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, 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.timerservice.quartz; - -import java.io.Serializable; - -import javax.ejb.EJBException; -import javax.ejb.NoSuchObjectLocalException; -import javax.ejb.Timer; -import javax.ejb.TimerHandle; -import javax.management.ObjectName; - -import org.jboss.ejb3.Ejb3Registry; -import org.jboss.ejb3.timerservice.TimedObjectInvoker; -import org.jboss.logging.Logger; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.Trigger; - -/** - * This class contains all the info for find a persistent timer. - * - * @author Carlo de Wolf - * @version $Revision$ - */ -public class PersistentTimer implements Serializable, TimerHandle -{ - private static final Logger log = Logger.getLogger(PersistentTimer.class); - - private static final long serialVersionUID = 1L; - - //private String schedulerName; - //private String jobName; - //private String jobGroup; - private String triggerName; - private String triggerGroup; - private String containerGuid; - - private Serializable info; - - protected PersistentTimer(Trigger trigger, String containerGuid, Serializable info) - { - assert trigger != null; - assert containerGuid != null; - - this.triggerName = trigger.getName(); - this.triggerGroup = trigger.getGroup(); - this.info = info; - this.containerGuid = containerGuid; - } - - protected TimedObjectInvoker getTimedObjectInvoker() - { - // TODO: a hack to get back the container. This needs thinking. - TimedObjectInvoker invoker = (TimedObjectInvoker) Ejb3Registry.getContainer(containerGuid); - assert invoker != null; - return invoker; - } - - public Timer getTimer() throws IllegalStateException, NoSuchObjectLocalException, EJBException - { - // TODO: check state - try - { - Scheduler scheduler = QuartzTimerServiceFactory.getScheduler(); - Trigger trigger = scheduler.getTrigger(triggerName, triggerGroup); - if(trigger == null) - throw new NoSuchObjectLocalException("can't find trigger '" + triggerName + "' in group '" + triggerGroup + "'"); - return new TimerImpl(scheduler, trigger, info); - } - catch(SchedulerException e) - { - log.error("getTimer failed", e); - throw new EJBException(e); - } - } -} Index: core/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerJob.java =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerJob.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/quartz/QuartzTimerJob.java (working copy) @@ -1,48 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, 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.timerservice.quartz; - -import org.jboss.ejb3.timerservice.TimedObjectInvoker; -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; - -/** - * Comment - * - * @author Carlo de Wolf - * @version $Revision$ - */ -public class QuartzTimerJob implements Job -{ - public void execute(JobExecutionContext context) throws JobExecutionException - { - PersistentTimer timer = (PersistentTimer) context.getJobDetail().getJobDataMap().get("timer"); - TimedObjectInvoker invoker = timer.getTimedObjectInvoker(); - try { - invoker.callTimeout(timer.getTimer()); - } - catch(Exception e) { - throw new JobExecutionException(e); - } - } -} Index: core/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerImpl.java =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerImpl.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerImpl.java (working copy) @@ -1,152 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, 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.timerservice.quartz; - -import java.io.Serializable; -import java.util.Date; - -import javax.ejb.EJBException; -import javax.ejb.NoSuchObjectLocalException; -import javax.ejb.Timer; -import javax.ejb.TimerHandle; - -import org.jboss.logging.Logger; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.Trigger; - -/** - * A view on an actual (persistent) timer. - * - * This object must never be serializable (EJB3 18.4.1) - * - * @author Carlo de Wolf - * @version $Revision$ - */ -public class TimerImpl implements Timer -{ - private static final Logger log = Logger.getLogger(TimerImpl.class); - - private Scheduler scheduler; - private Trigger trigger; - private Serializable info; - - protected TimerImpl(Scheduler scheduler, Trigger trigger, Serializable info) { - assert scheduler != null; - assert trigger != null; - - this.scheduler = scheduler; - this.trigger = trigger; - this.info = info; - } - - protected void checkState() - { - // TODO: implement bean state checking to see if a call is allowed - - if(trigger.getNextFireTime() == null) - throw new NoSuchObjectLocalException("timer has expired"); - } - - /** - * Cause the timer and all its associated expiration notifications to be cancelled. - * - * @throws IllegalStateException If this method is invoked while the instance is in a state that does not allow access to this method. - * @throws NoSuchObjectLocalException If invoked on a timer that has expired or has been cancelled. - * @throws EJBException If this method could not complete due to a system-level failure. - */ - public void cancel() throws IllegalStateException, NoSuchObjectLocalException, EJBException - { - checkState(); - - try { - // TODO: call TimerServiceImpl.cancelTimer instead - scheduler.unscheduleJob(trigger.getName(), trigger.getGroup()); - } - catch(SchedulerException e) { - log.error("cancel failed", e); - throw new EJBException(e.getMessage()); - } - } - - /** - * Get the number of milliseconds that will elapse before the next scheduled timer expiration. - * - * @return The number of milliseconds that will elapse before the next scheduled timer expiration. - * @throws IllegalStateException If this method is invoked while the instance is in a state that does not allow access to this method. - * @throws NoSuchObjectLocalException If invoked on a timer that has expired or has been cancelled. - * @throws EJBException If this method could not complete due to a system-level failure. - */ - public long getTimeRemaining() throws IllegalStateException, NoSuchObjectLocalException, EJBException - { - // leave all checks to getNextTimeout - return getNextTimeout().getTime() - System.currentTimeMillis(); - } - - /** - * Get the point in time at which the next timer expiration is scheduled to occur. - * - * @return The point in time at which the next timer expiration is scheduled to occur. - * @throws IllegalStateException If this method is invoked while the instance is in a state that does not allow access to this method. - * @throws NoSuchObjectLocalException If invoked on a timer that has expired or has been cancelled. - * @throws EJBException If this method could not complete due to a system-level failure. - */ - public Date getNextTimeout() throws IllegalStateException, NoSuchObjectLocalException, EJBException - { - checkState(); - - Date nextTimeout = trigger.getNextFireTime(); - if(nextTimeout == null) - throw new IllegalStateException("trigger does not have a next fire time"); // TODO: proper EJB3 state check & exception - return nextTimeout; - } - - /** - * Get the information associated with the timer at the time of creation. - * - * @return The Serializable object that was passed in at timer creation, or null if the info argument passed in at timer creation was null. - * @throws IllegalStateException If this method is invoked while the instance is in a state that does not allow access to this method. - * @throws NoSuchObjectLocalException If invoked on a timer that has expired or has been cancelled. - * @throws EJBException If this method could not complete due to a system-level failure. - */ - public Serializable getInfo() throws IllegalStateException, NoSuchObjectLocalException, EJBException - { - checkState(); - - return info; - } - - /** - * Get a serializable handle to the timer. This handle can be used at a later time to re-obtain the timer reference. - * - * @return A serializable handle to the timer. - * @throws IllegalStateException If this method is invoked while the instance is in a state that does not allow access to this method. - * @throws NoSuchObjectLocalException If invoked on a timer that has expired or has been cancelled. - * @throws EJBException If this method could not complete due to a system-level failure. - */ - public TimerHandle getHandle() throws IllegalStateException, NoSuchObjectLocalException, EJBException - { - checkState(); - - return null; // FIXME: implement getHandle - } -} Index: core/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerServiceImpl.java =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerServiceImpl.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/quartz/TimerServiceImpl.java (working copy) @@ -1,238 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, 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.timerservice.quartz; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Date; - -import javax.ejb.EJBException; -import javax.ejb.Timer; -import javax.ejb.TimerService; -import javax.management.ObjectName; - -import org.jboss.ejb3.Container; -import org.jboss.ejb3.Ejb3Registry; -import org.jboss.ejb3.timerservice.TimedObjectInvoker; -import org.jboss.logging.Logger; -import org.quartz.JobDetail; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.SimpleTrigger; -import org.quartz.Trigger; - -/** - * Implements the EJB3 Timer Service specification (EJB3 chapter 18). - * - * Each bean container has its own job and trigger group. - * - * @author Carlo de Wolf - * @version $Revision$ - */ -public class TimerServiceImpl implements TimerService -{ - private static final Logger log = Logger.getLogger(TimerServiceImpl.class); - - private Scheduler scheduler; - private Container container; - private ObjectName objectName; - private String groupName; - private long jobNum = 0; - private long triggerNum = 0; - - protected TimerServiceImpl(Scheduler scheduler, Container container, TimedObjectInvoker invoker) { - assert scheduler != null; - assert objectName != null; - assert container != null; - assert invoker != null; - - this.scheduler = scheduler; - this.container = container; - this.objectName = container.getObjectName(); - this.groupName = objectName.getCanonicalName(); - } - - protected Timer createTimer(Trigger trigger, Serializable info) - { - try { - String name = "myJob" + jobNum; - jobNum++; - - Class jobClass = QuartzTimerJob.class; - - Timer timer = new TimerImpl(scheduler, trigger, info); - - PersistentTimer persistentTimer = new PersistentTimer(trigger, Ejb3Registry.guid(container), info); - - JobDetail jobDetail = new JobDetail(name, groupName, jobClass); - jobDetail.getJobDataMap().put("timer", persistentTimer); - - scheduler.scheduleJob(jobDetail, trigger); - - return timer; - } - catch(SchedulerException e) { - // translate the exception, because the client might not have quartz - log.error("createTimer failed", e); - throw new EJBException(e.getMessage()); - } - - } - - /** - * Create a single-action timer that expires after a specified duration. - * - * @param duration The number of milliseconds that must elapse before the timer expires. - * @param info Application information to be delivered along with the timer expiration notification. This can be null. - * @return The newly created Timer. - * @throws IllegalArgumentException If duration is negative. - * @throws IllegalStateException If this method is invoked while the instance is in a state that does not allow access to this method. - * @throws EJBException If this method fails due to a system-level failure. - */ - public Timer createTimer(long duration, Serializable info) throws IllegalArgumentException, IllegalStateException, - EJBException - { - if(duration < 0) throw new IllegalArgumentException("duration must not be negative"); - // TODO: check state - - Date expiration = new Date(System.currentTimeMillis() + duration); - return createTimer(expiration, info); - } - - /** - * Create an interval timer whose first expiration occurs after a specified duration, - * and whose subsequent expirations occur after a specified interval. - * - * @param initialDuration The number of milliseconds that must elapse before the first timer expiration notification. - * @param intervalDuration The number of milliseconds that must elapse between timer expiration notifications. Expiration notifications are scheduled relative to the time of the first expiration. If expiration is delayed(e.g. due to the interleaving of other method calls on the bean) two or more expiration notifications may occur in close succession to "catch up". - * @param info Application information to be delivered along with the timer expiration. This can be null. - * @return The newly created Timer. - * @throws IllegalArgumentException If initialDuration is negative, or intervalDuration is negative. - * @throws IllegalStateException If this method is invoked while the instance is in a state that does not allow access to this method. - * @throws EJBException If this method could not complete due to a system-level failure. - */ - public Timer createTimer(long initialDuration, long intervalDuration, Serializable info) - throws IllegalArgumentException, IllegalStateException, EJBException - { - if(initialDuration < 0) throw new IllegalArgumentException("initialDuration must not be negative"); - if(intervalDuration < 0) throw new IllegalArgumentException("intervalDuration must not be negative"); - // TODO: check state - - Date initialExpiration = new Date(System.currentTimeMillis() + initialDuration); - - return createTimer(initialExpiration, intervalDuration, info); - } - - /** - * Create a single-action timer that expires at a given point in time. - * - * @param expiration The point in time at which the timer must expire. - * @param info Application information to be delivered along with the timer expiration notification. This can be null. - * @return The newly created Timer. - * @throws IllegalArgumentException If expiration is null, or expiration.getTime() is negative. - * @throws IllegalStateException If this method is invoked while the instance is in a state that does not allow access to this method. - * @throws EJBException If this method could not complete due to a system-level failure. - */ - public Timer createTimer(Date expiration, Serializable info) throws IllegalArgumentException, IllegalStateException, - EJBException - { - if(expiration == null) throw new IllegalArgumentException("expiration must not be null"); - if(expiration.getTime() < 0) throw new IllegalArgumentException("expiration.time must not be negative"); - // TODO: check state - - String triggerName = "myTrigger" + triggerNum; - triggerNum++; - - Trigger trigger = new SimpleTrigger(triggerName, groupName, expiration); - - return createTimer(trigger, info); - } - - /** - * Create an interval timer whose first expiration occurs at a given point in time and whose subsequent expirations occur after a specified interval. - * - * @param initialExpiration The point in time at which the first timer expiration must occur. - * @param intervalDuration The number of milliseconds that must elapse between timer expiration notifications. Expiration notifications are scheduled relative to the time of the first expiration. If expiration is delayed(e.g. due to the interleaving of other method calls on the bean) two or more expiration notifications may occur in close succession to "catch up". - * @param info Application information to be delivered along with the timer expiration notification. This can be null. - * @return The newly created Timer. - * @throws IllegalArgumentException If initialExpiration is null, or initialExpiration.getTime() is negative, or intervalDuration is negative. - * @throws IllegalStateException If this method is invoked while the instance is in a state that does not allow access to this method. - * @throws EJBException If this method could not complete due to a system-level failure. - */ - public Timer createTimer(Date initialExpiration, long intervalDuration, Serializable info) - throws IllegalArgumentException, IllegalStateException, EJBException - { - if(initialExpiration == null) throw new IllegalArgumentException("initialExpiration must not be null"); - if(initialExpiration.getTime() < 0) throw new IllegalArgumentException("initialExpiration.time must not be negative"); - if(intervalDuration < 0) throw new IllegalArgumentException("intervalDuration must not be negative"); - // TODO: check state - - String triggerName = "myTrigger" + triggerNum; - triggerNum++; - Date endTime = null; - - Trigger trigger = new SimpleTrigger(triggerName, groupName, initialExpiration, endTime, SimpleTrigger.REPEAT_INDEFINITELY, intervalDuration); - - return createTimer(trigger, info); - } - - protected Scheduler getScheduler() - { - return scheduler; - } - - /** - * Get all the active timers associated with this bean. - * - * @return A collection of javax.ejb.Timer objects. - * @throws IllegalStateException If this method is invoked while the instance is in a state that does not allow access to this method. - * @throws EJBException If this method could not complete due to a system-level failure. - */ - public Collection getTimers() throws IllegalStateException, EJBException - { - throw new RuntimeException("NYI"); - } - - protected void shutdown() - { - log.debug("shutting down " + this); - try - { - String triggerNames[] = scheduler.getTriggerNames(groupName); - for(String triggerName : triggerNames) - scheduler.unscheduleJob(triggerName, groupName); - String jobNames[] = scheduler.getJobNames(groupName); - for(String jobName : jobNames) - scheduler.deleteJob(jobName, groupName); - } - catch(SchedulerException e) - { - log.error("shutdown failed", e); - // TODO: ignore? - } - } - - public String toString() - { - return "Timer Service " + objectName; - } -} Index: core/src/main/java/org/jboss/ejb3/timerservice/quartz/jmx/EJB3TimerService.java =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/quartz/jmx/EJB3TimerService.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/quartz/jmx/EJB3TimerService.java (working copy) @@ -1,114 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, 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.timerservice.quartz.jmx; - -import java.util.Properties; - -import javax.management.ObjectName; - -import org.jboss.ejb3.timerservice.quartz.QuartzTimerServiceFactory; -import org.jboss.system.ServiceMBeanSupport; - -/** - * Comment - * - * @author Carlo de Wolf - * @version $Revision$ - */ -public class EJB3TimerService extends ServiceMBeanSupport - implements EJB3TimerServiceMBean -{ - private QuartzTimerServiceFactory delegate; - private ObjectName dataSource; - - public EJB3TimerService() - { - delegate = new QuartzTimerServiceFactory(); - } - - @Override - protected void createService() throws Exception - { - super.createService(); - } - - @Override - protected void destroyService() throws Exception - { - //this.delegate.shutdown(); - super.destroyService(); - } - - /** - * @jmx:managed-attribute - * - * @return the object name of the data source to use - */ - public ObjectName getDataSource() - { - return dataSource; - } - - /** - * @jmx:managed-attribute - */ - public void setDataSource(ObjectName dataSource) - { - this.dataSource = dataSource; - } - - /** - * @jmx:managed-attribute - * - * @param props - */ - public void setProperties(final Properties props) - { - delegate.setProperties(props); - } - - /** - * @jmx:managed-attribute - * - * @param props - */ - public void setSqlProperties(Properties props) - { - delegate.setSqlProperties(props); - } - - @Override - protected void startService() throws Exception - { - super.startService(); - String jndiName = (String) server.getAttribute(dataSource, "BindName"); - delegate.setDataSource(jndiName); - delegate.start(); - } - - @Override - protected void stopService() throws Exception - { - delegate.stop(); - super.stopService(); - } -} Index: core/src/main/java/org/jboss/ejb3/timerservice/quartz/jmx/EJB3TimerServiceMBean.java =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/quartz/jmx/EJB3TimerServiceMBean.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/quartz/jmx/EJB3TimerServiceMBean.java (working copy) @@ -1,47 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, 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.timerservice.quartz.jmx; - -import java.util.Properties; - -import javax.management.ObjectName; - -import org.jboss.mx.util.ObjectNameFactory; -import org.jboss.system.ServiceMBean; - -/** - * Comment - * - * @author Carlo de Wolf - * @version $Revision$ - */ -public interface EJB3TimerServiceMBean extends ServiceMBean -{ - /** The default object name */ - ObjectName OBJECT_NAME = ObjectNameFactory.create("jboss.ejb:service=EJB3TimerService"); - - void setDataSource(ObjectName dataSource); - - void setProperties(final Properties props); - - void setSqlProperties(Properties props); -} Index: core/src/main/java/org/jboss/ejb3/timerservice/quartz/package.html =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/quartz/package.html (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/quartz/package.html (working copy) @@ -1,17 +0,0 @@ - - - This package provides the EJB Timer Service to the EJB3 stack. -

- It replaces the org.jboss.ejb.txtimer package. -

- The Jboss EJB3 Timer Service package depends on: -

-

- Note that almost all exceptions are caught and rethrown as EJBExceptions, thus - making sure that no Quartz API is exposed either compile time or run time. - - \ No newline at end of file Index: core/src/main/java/org/jboss/ejb3/timerservice/TimedObjectInvoker.java =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/TimedObjectInvoker.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/TimedObjectInvoker.java (working copy) @@ -1,47 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, 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.timerservice; - -// $Id: TimedObjectInvoker.java,v 1.1 2006/06/07 09:26:15 wolfc Exp $ - -import javax.ejb.Timer; - -/** - * An implementation can invoke the ejbTimeout method on a TimedObject. - * - * The TimedObjectInvoker has knowledge of the TimedObjectId, it - * knows which object to invoke. - * - * @author Thomas.Diesler@jboss.org - * @version $Revision: 1.1 $ - * @since 07-Apr-2004 - */ -public interface TimedObjectInvoker extends org.jboss.ejb.txtimer.TimedObjectInvoker -{ - /** - * Invokes the ejbTimeout method on the TimedObject with the given id. - * - * @param timer the Timer that is passed to ejbTimeout - */ - void callTimeout(Timer timer) throws Exception; - -} Index: core/src/main/java/org/jboss/ejb3/timerservice/TimerServiceFactory.java =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/TimerServiceFactory.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/TimerServiceFactory.java (working copy) @@ -1,89 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, 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.timerservice; - -import javax.ejb.EJBException; -import javax.ejb.TimerService; -import javax.management.ObjectName; - -import org.jboss.ejb3.Container; - -/** - * Comment - * - * @author Carlo de Wolf - * @version $Revision: $ - */ -public abstract class TimerServiceFactory -{ - private static TimerServiceFactory instance; - - private synchronized static TimerServiceFactory createInstance() - { - if(instance != null) - return instance; - - String factoryClass = "org.jboss.ejb3.timerservice.jboss.JBossTimerServiceFactory"; - factoryClass = System.getProperty("org.jboss.ejb3.timerservice.factory", factoryClass); - - try - { - Class cls = Class.forName(factoryClass); - instance = (TimerServiceFactory) cls.newInstance(); - - return instance; - } - catch(ClassNotFoundException e) - { - throw new EJBException(e); - } - catch(InstantiationException e) - { - throw new EJBException(e); - } - catch(IllegalAccessException e) - { - throw new EJBException(e); - } - } - - public abstract TimerService createTimerService(Container container, TimedObjectInvoker invoker); - - public static TimerServiceFactory getInstance() - { - if(instance == null) - { - createInstance(); - } - - return instance; - } - - public abstract void removeTimerService(TimerService timerService); - - /** - * Restores the timers held with the specified timer service. - * - * @param timerService - */ - public abstract void restoreTimerService(TimerService timerService); -} Index: core/src/main/java/org/jboss/ejb3/timerservice/package.html =================================================================== --- core/src/main/java/org/jboss/ejb3/timerservice/package.html (revision 83558) +++ core/src/main/java/org/jboss/ejb3/timerservice/package.html (working copy) @@ -1,5 +0,0 @@ - - -This package forms the bridge between EJB3 and a timer service. - - \ No newline at end of file Index: core/src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java =================================================================== --- core/src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java (revision 83558) +++ core/src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java (working copy) @@ -39,6 +39,7 @@ import org.jboss.aop.Domain; import org.jboss.aop.MethodInfo; +import org.jboss.beans.metadata.api.annotations.Inject; import org.jboss.deployers.spi.DeploymentException; import org.jboss.ejb3.BeanContext; import org.jboss.ejb3.EJBContainer; @@ -49,8 +50,8 @@ import org.jboss.ejb3.jms.JMSDestinationFactory; import org.jboss.ejb3.mdb.inflow.JBossMessageEndpointFactory; import org.jboss.ejb3.proxy.factory.ProxyFactoryHelper; -import org.jboss.ejb3.timerservice.TimedObjectInvoker; -import org.jboss.ejb3.timerservice.TimerServiceFactory; +import org.jboss.ejb3.timerservice.spi.TimedObjectInvoker; +import org.jboss.ejb3.timerservice.spi.TimerServiceFactory; import org.jboss.jms.jndi.JMSProviderAdapter; import org.jboss.logging.Logger; import org.jboss.metadata.ejb.jboss.JBossEnterpriseBeanMetaData; @@ -71,6 +72,8 @@ protected JBossMessageEndpointFactory messageEndpointFactory; private MessagingDelegateWrapper mbean = new MessagingDelegateWrapper(this); + private TimerServiceFactory timerServiceFactory; + /** * Default destination type. Used when no message-driven-destination is given * in ejb-jar, and a lookup of destinationJNDI from jboss.xml is not @@ -168,11 +171,11 @@ innerStart(); - timerService = TimerServiceFactory.getInstance().createTimerService(this, this); + timerService = timerServiceFactory.createTimerService(this); startProxies(); - TimerServiceFactory.getInstance().restoreTimerService(timerService); + timerServiceFactory.restoreTimerService(timerService); } protected void innerStart() throws Exception @@ -299,7 +302,7 @@ { if (timerService != null) { - TimerServiceFactory.getInstance().removeTimerService(timerService); + timerServiceFactory.suspendTimerService(timerService); timerService = null; } @@ -620,4 +623,18 @@ else return 60000; } + + /* (non-Javadoc) + * @see org.jboss.ejb3.timerservice.spi.TimedObjectInvoker#getTimedObjectId() + */ + public String getTimedObjectId() + { + return getDeploymentQualifiedName(); + } + + @Inject + public void setTimerServiceFactory(TimerServiceFactory factory) + { + this.timerServiceFactory = factory; + } } \ No newline at end of file Index: core/src/main/resources/ejb3-timer-service.xml =================================================================== --- core/src/main/resources/ejb3-timer-service.xml (revision 83558) +++ core/src/main/resources/ejb3-timer-service.xml (working copy) @@ -1,88 +0,0 @@ - - - - - - - - - - jboss:service=Naming - jboss:service=TransactionManager - jboss.jca:service=DataSourceBinding,name=DefaultDS - - - org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreCMT - org.quartz.jobStore.nonManagedTXDataSource=myDS - org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate - org.quartz.jobStore.tablePrefix=QRTZ_ - org.quartz.jobStore.dataSource=myDS - - # To get it to work with hypersonic - # FIXME: this doesn't lock the row - org.quartz.jobStore.selectWithLockSQL=SELECT * FROM QRTZ_LOCKS WHERE lock_name = ? - - # from quartz.properties - org.quartz.scheduler.instanceName=JBossEJB3QuartzScheduler - org.quartz.scheduler.rmi.export=false - org.quartz.scheduler.rmi.proxy=false - org.quartz.scheduler.wrapJobExecutionInUserTransaction=false - - org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool - org.quartz.threadPool.threadCount=10 - org.quartz.threadPool.threadPriority=5 - org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true - - org.quartz.jobStore.misfireThreshold=60000 - - - CREATE_DB_ON_STARTUP = TRUE - - CREATE_TABLE_JOB_DETAILS = CREATE TABLE QRTZ_JOB_DETAILS(JOB_NAME VARCHAR(80) NOT NULL, JOB_GROUP VARCHAR(80) NOT NULL, \ - DESCRIPTION VARCHAR(120) NULL, JOB_CLASS_NAME VARCHAR(128) NOT NULL, IS_DURABLE VARCHAR(1) NOT NULL, \ - IS_VOLATILE VARCHAR(1) NOT NULL, IS_STATEFUL VARCHAR(1) NOT NULL, REQUESTS_RECOVERY VARCHAR(1) NOT NULL, \ - JOB_DATA BINARY NULL, PRIMARY KEY (JOB_NAME,JOB_GROUP)) - CREATE_TABLE_JOB_LISTENERS = CREATE TABLE QRTZ_JOB_LISTENERS(JOB_NAME VARCHAR(80) NOT NULL, JOB_GROUP VARCHAR(80) NOT NULL, \ - JOB_LISTENER VARCHAR(80) NOT NULL, PRIMARY KEY (JOB_NAME,JOB_GROUP,JOB_LISTENER), FOREIGN KEY (JOB_NAME,JOB_GROUP) \ - REFERENCES QRTZ_JOB_DETAILS(JOB_NAME,JOB_GROUP)) - CREATE_TABLE_TRIGGERS = CREATE TABLE QRTZ_TRIGGERS(TRIGGER_NAME VARCHAR(80) NOT NULL, TRIGGER_GROUP VARCHAR(80) NOT NULL, \ - JOB_NAME VARCHAR(80) NOT NULL, JOB_GROUP VARCHAR(80) NOT NULL, IS_VOLATILE VARCHAR(1) NOT NULL, DESCRIPTION VARCHAR(120) NULL, \ - NEXT_FIRE_TIME NUMERIC(13) NULL, PREV_FIRE_TIME NUMERIC(13) NULL, TRIGGER_STATE VARCHAR(16) NOT NULL, \ - TRIGGER_TYPE VARCHAR(8) NOT NULL, START_TIME NUMERIC(13) NOT NULL, END_TIME NUMERIC(13) NULL, CALENDAR_NAME VARCHAR(80) NULL, \ - MISFIRE_INSTR NUMERIC(2) NULL, JOB_DATA BINARY NULL, PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP), FOREIGN KEY (JOB_NAME,JOB_GROUP) \ - REFERENCES QRTZ_JOB_DETAILS(JOB_NAME,JOB_GROUP)) - CREATE_TABLE_SIMPLE_TRIGGERS = CREATE TABLE QRTZ_SIMPLE_TRIGGERS(TRIGGER_NAME VARCHAR(80) NOT NULL, \ - TRIGGER_GROUP VARCHAR(80) NOT NULL, REPEAT_COUNT NUMERIC(7) NOT NULL, REPEAT_INTERVAL NUMERIC(12) NOT NULL, \ - TIMES_TRIGGERED NUMERIC(7) NOT NULL, PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP), FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP) \ - REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP)) - CREATE_TABLE_CRON_TRIGGERS = CREATE TABLE QRTZ_CRON_TRIGGERS(TRIGGER_NAME VARCHAR(80) NOT NULL, \ - TRIGGER_GROUP VARCHAR(80) NOT NULL, CRON_EXPRESSION VARCHAR(80) NOT NULL, TIME_ZONE_ID VARCHAR(80), \ - PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP), FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP) \ - REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP)) - CREATE_TABLE_BLOB_TRIGGERS = CREATE TABLE QRTZ_BLOB_TRIGGERS(TRIGGER_NAME VARCHAR(80) NOT NULL, \ - TRIGGER_GROUP VARCHAR(80) NOT NULL, BLOB_DATA BINARY NULL, PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP), \ - FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP) REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP)) - CREATE_TABLE_TRIGGER_LISTENERS = CREATE TABLE QRTZ_TRIGGER_LISTENERS(TRIGGER_NAME VARCHAR(80) NOT NULL, \ - TRIGGER_GROUP VARCHAR(80) NOT NULL, TRIGGER_LISTENER VARCHAR(80) NOT NULL, \ - PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_LISTENER), FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP) \ - REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP)) - CREATE_TABLE_CALENDARS = CREATE TABLE QRTZ_CALENDARS(CALENDAR_NAME VARCHAR(80) NOT NULL, CALENDAR BINARY NOT NULL, \ - PRIMARY KEY (CALENDAR_NAME)) - CREATE_TABLE_PAUSED_TRIGGER_GRPS = CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS(TRIGGER_GROUP VARCHAR(80) NOT NULL, \ - PRIMARY KEY (TRIGGER_GROUP)) - CREATE_TABLE_FIRED_TRIGGERS = CREATE TABLE QRTZ_FIRED_TRIGGERS(ENTRY_ID VARCHAR(95) NOT NULL, TRIGGER_NAME VARCHAR(80) NOT NULL, \ - TRIGGER_GROUP VARCHAR(80) NOT NULL, IS_VOLATILE VARCHAR(1) NOT NULL, INSTANCE_NAME VARCHAR(80) NOT NULL, \ - FIRED_TIME NUMERIC(13) NOT NULL, STATE VARCHAR(16) NOT NULL, JOB_NAME VARCHAR(80) NULL, JOB_GROUP VARCHAR(80) NULL, \ - IS_STATEFUL VARCHAR(1) NULL, REQUESTS_RECOVERY VARCHAR(1) NULL, PRIMARY KEY (ENTRY_ID)) - CREATE_TABLE_SCHEDULER_STATE = CREATE TABLE QRTZ_SCHEDULER_STATE(INSTANCE_NAME VARCHAR(80) NOT NULL, \ - LAST_CHECKIN_TIME NUMERIC(13) NOT NULL, CHECKIN_INTERVAL NUMERIC(13) NOT NULL, RECOVERER VARCHAR(80) NULL, \ - PRIMARY KEY (INSTANCE_NAME)) - CREATE_TABLE_LOCKS = CREATE TABLE QRTZ_LOCKS(LOCK_NAME VARCHAR(40) NOT NULL, PRIMARY KEY (LOCK_NAME)) - INSERT_TRIGGER_ACCESS = INSERT INTO QRTZ_LOCKS values('TRIGGER_ACCESS') - INSERT_JOB_ACCESS = INSERT INTO QRTZ_LOCKS values('JOB_ACCESS') - INSERT_CALENDAR_ACCESS = INSERT INTO QRTZ_LOCKS values('CALENDAR_ACCESS') - INSERT_STATE_ACCESS = INSERT INTO QRTZ_LOCKS values('STATE_ACCESS') - INSERT_MISFIRE_ACCESS = INSERT INTO QRTZ_LOCKS values('MISFIRE_ACCESS') - - - Index: core/pom.xml =================================================================== --- core/pom.xml (revision 83558) +++ core/pom.xml (working copy) @@ -17,7 +17,7 @@ jboss-ejb3-core jar - 1.0.1-SNAPSHOT + 1.1.0-SNAPSHOT JBoss EJB 3.0 Core http://labs.jboss.com/jbossejb3 JBoss EJB 3.0 Core @@ -369,6 +369,12 @@ org.jboss.ejb3 + jboss-ejb3-timerservice-spi + [0,) + + + + org.jboss.ejb3 jboss-ejb3-ext-api 1.0.0