7 Replies Latest reply on Dec 19, 2006 5:28 AM by dilator

    Quartz TimerService

    dilator

      Hi guys,

      Sorry this is a little off topic - i've asked in the EJB3 forum but got no response - it seems quite dead in there!

      Has anybody managed to get the Quartz EJB3 timer implementation working? If so could anyone point me in the right direction?

      Many thanks - Ben

        • 1. Re: Quartz TimerService

          Seam: "We're friendlier than plain EJB3 too"

          Unfortunately, I don't have an answer for you either. I just wanted to echo that I tried the seampay example with the instructions for using Quartz, and it also failed. Hopefully we can get someone to document how to use it.




          • 2. Re: Quartz TimerService
            msduk

            This worked fine for me. I have the quartz jar in the lib folder and I believe that was it. This is on 4.0.5 GA.

            I noticed that I have jobs.xml, .properties and the xsd in my WEB-INF from an earlier attempt to run it the non-ejb way. Maybe it requires this?

            @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "cronTrigger", propertyValue = "0/15 * * * * ?") })
            @ResourceAdapter("quartz-ra.rar")
            
            public class TestQuartzTarget implements Job {
            
             @PersistenceContext
             EntityManager em;
            
             private static final Logger log = Logger
             .getLogger(TestQuartzTarget.class);
            
             public PendingOrderQuartzTarget() {
             super();
             System.out.println("Quartz-bean is constructed()");
             }
            
             public void execute(JobExecutionContext jobExecutionContext)
             throws JobExecutionException {
            
             long start = System.currentTimeMillis();
            
             log.debug(this.getClass().getName() + " STARTING RUN");
             log.debug(em);
            
             //Do your work here
            
             log.debug(this.getClass().getName() + " FINISHING RUN");
             log.debug("RUNTIME: " + (System.currentTimeMillis() - start) + " ms");
             }
            
            }


            From web.xml

            <servlet>
             <servlet-name>QuartzInitializer</servlet-name>
             <servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
            
             <init-param>
             <param-name>config-file</param-name>
             <param-value>quartz-nrg2.properties</param-value>
             </init-param>
            
             <init-param>
             <param-name>shutdown-on-unload</param-name>
             <param-value>true</param-value>
             </init-param>
            
             <init-param>
             <param-name>start-scheduler-on-load</param-name>
             <param-value>true</param-value>
             </init-param>
             <load-on-startup>1</load-on-startup>
             </servlet>


            • 3. Re: Quartz TimerService
              dilator

              I've not tried using Quartz via the resource adapter - I'll have to check that out. I was more interested in using Quartz as a drop-in replacement for the EJB TimerService.

              My main reason for this is I would like to create an arbitrarily large set of timers (for example 2 or 3 timers for each user on a website). As I understand (and have done a bit of testing which confirms this), that whilst the default TimerService implementation uses java.util.Timer, it creates a new java.util.Timer for every ejb Timer requested, rather than scheduling a new entry on an existing Timer - so basically 1 thread per ejb Timer, which obviously does not scale. As far as I can see there is no reason why this could not be implemented differently?

              Anyways http://jira.jboss.org/jira/browse/EJBTHREE-619 says you simply have to change a system property to get the Quartz implementation running. I've done this, and can see that the QuartzTimerServiceFactory is being created, but no TimerServices are being injected anymore, so something isn't quite right...

              I'm suprised I don't have to change anything in the ejb-timer-service.xml?

              Thanks again - i'll cross post this to the EJB3 forum too

              ben

              • 4. Re: Quartz TimerService
                dilator

                Ok getting a bit closer - been rooting about FishEye and I came across a new ejb-timer-service.xml yay!

                <?xml version="1.0" encoding="UTF-8"?>
                <server>
                 <!-- TODO: the ejb deployer must depend on this -->
                
                 <!-- ================================================ -->
                 <!-- Defines the Quartz configuration for -->
                 <!-- the EJB3 Timer Service -->
                 <!-- ================================================ -->
                 <mbean code="org.jboss.ejb3.timerservice.quartz.jmx.EJB3TimerService" name="jboss.ejb:service=EJB3TimerService">
                 <depends>jboss:service=Naming</depends>
                
                 <depends>jboss:service=TransactionManager</depends>
                 <depends optional-attribute-name="DataSource">jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
                
                 <attribute name="Properties">
                 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
                 </attribute>
                 <attribute name="SqlProperties">
                 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')
                 </attribute>
                
                 </mbean>
                </server>
                


                And that seems to get the Quartz implementation going. But looks like it's not quite finished :D

                Caused by: java.lang.RuntimeException: NYI
                 at org.jboss.ejb3.timerservice.quartz.TimerServiceImpl.getTimers(TimerServiceImpl.java:207)
                


                Getting there!

                • 5. Re: Quartz TimerService
                  msduk

                  I have the calendar defined in jobs.xml

                  • 6. Re: Quartz TimerService
                    wolfc

                    The QuartzTimerService implementation is a prototype to see if it could be done, but Scott pointed out that it is yet another timer service into JBoss AS. Which is something we don't want, so implementation was postponed.
                    There is going to be an unified enterprise timer service, possibly based on Quartz.
                    For now the EJB3 QuartzTimerService is on hold and will not be continued upon.

                    • 7. Re: Quartz TimerService
                      dilator

                      Thanks for your reply,

                      Agreed - it's a shame nevertheless - it seems like it would be more scalable than the standard implementation and it looks like it's almost there!