4 Replies Latest reply on Mar 14, 2012 12:40 PM by Roger Mori

    latest version of Quartz that will work with Seam 2.2

    gebuh Newbie

      Does anyone know what that is?  It looks like Seam 2.2 comes with quartz 1.6.  When I upgraded the quartz jar to the quartz 2.1.1.  My deployment fails with a stacktrace that leads to a java.lang.InstantiationError: org.quartz.JobDetail error. 
      Seam's QuartzDispatcher scheduleWithQuartzService tries to create the JobDetail object:




       private QuartzTriggerHandle scheduleWithQuartzService(Schedule schedule, Asynchronous async) throws SchedulerException, ParseException
         {
            String jobName = nextUniqueName();
            String triggerName = nextUniqueName();
            
            JobDetail jobDetail = new JobDetail(jobName, null, QuartzJob.class);
      
      ...
      





      When I compare 2.1.1 with 1.6.6.  I see that in quartz 2.1.1 JobDetail constructor is:




       public JobDetailImpl(String name, String group, Class<? extends Job> jobClass) {
              setName(name);
              setGroup(group);
              setJobClass(jobClass);
          }



      in quartz 1.6.6 it's:



           public JobDetail(String name, String group, Class jobClass) {
              setName(name);
              setGroup(group);
              setJobClass(jobClass);




          }


      QuartzJob implements Job, but for 2.1.1 it requires that it extend Job, so it doesn't work.
      The reader's digest of all this sleuthing is; what is the latest version of Quartz I can use with Seam 2.2?
      Or would this qualify as a JIRA issue?  I don't know if there are other issues.  This is the 1st one I've found.

        • 1. Re: latest version of Quartz that will work with Seam 2.2
          Rob Shepherd Newbie

          I have successfully written new modules for Seam 2.2 to use quartz latest versions


          This was done under a contract for a client, so I will need to ask them if we can release this portion of code.





          • 2. Re: latest version of Quartz that will work with Seam 2.2
            gebuh Newbie

            Rob Shepherd wrote on Jan 31, 2012 09:41:


            I have successfully written new modules for Seam 2.2 to use quartz latest versions

            This was done under a contract for a client, so I will need to ask them if we can release this portion of code.






            thanx Rob, did it require any other changes?

            • 3. Re: latest version of Quartz that will work with Seam 2.2
              Roger Mori Newbie

              Hi Beth:

               

               

              I have updated the Quartzdispatcher component in order have jboss-seam-2.2.2.Final working with Quartz 2.1.3

               

              Update your deployed-jars lists replace your current quartz.jar entry with quartz-all-2.1.3.jar.

               

              Also replace the Quartzdispatcher listed below with the one provided with seam. There exists several ways to do it.

               

              Hope it helps.

               

              Roger.

               

               

               

              package org.jboss.seam.async;

              import java.io.InputStream;
              import java.rmi.server.UID;
              import java.text.ParseException;
              import java.util.Date;

              import org.jboss.seam.Component;
              import org.jboss.seam.ScopeType;
              import org.jboss.seam.annotations.Create;
              import org.jboss.seam.annotations.Destroy;
              import org.jboss.seam.annotations.Install;
              import org.jboss.seam.annotations.Name;
              import org.jboss.seam.annotations.Scope;
              import org.jboss.seam.annotations.Startup;
              import org.jboss.seam.annotations.intercept.BypassInterceptors;
              import org.jboss.seam.intercept.InvocationContext;
              import org.jboss.seam.log.LogProvider;
              import org.jboss.seam.log.Logging;
              import org.quartz.Job;
              import org.quartz.JobDataMap;
              import org.quartz.JobExecutionContext;
              import org.quartz.JobExecutionException;
              import org.quartz.Scheduler;
              import org.quartz.SchedulerException;
              import org.quartz.impl.JobDetailImpl;
              import org.quartz.impl.StdSchedulerFactory;
              import org.quartz.impl.triggers.AbstractTrigger;
              import org.quartz.impl.triggers.CronTriggerImpl;
              import org.quartz.impl.triggers.SimpleTriggerImpl;


              @Startup
              @Scope(ScopeType.APPLICATION)
              @Name("org.jboss.seam.async.dispatcher")
              @Install(value=false, precedence=0)

              @BypassInterceptors
              public class QuartzDispatcher extends AbstractDispatcher<QuartzTriggerHandle, Schedule>
              {
                
                 private static final LogProvider log = Logging.getLogProvider(QuartzDispatcher.class);
                
                 private Scheduler scheduler;

                 @Create
                 public void initScheduler() throws SchedulerException
                 {
                     StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();

                     //TODO: magical properties files are *not* the way to config Seam apps!
                     InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("seam.quartz.properties");
                     if (is != null)
                     {
                       schedulerFactory.initialize(is);
                       log.debug("Found seam.quartz.properties file. Using it for Quartz config.");
                     }
                     else
                     {
                       schedulerFactory.initialize();
                       log.warn("No seam.quartz.properties file. Using in-memory job store.");
                     }
                 
                     scheduler = schedulerFactory.getScheduler();
                     scheduler.start();
                 }

                 public QuartzTriggerHandle scheduleAsynchronousEvent(String type, Object... parameters)
                 { 
                    String jobName = nextUniqueName();
                    String triggerName = nextUniqueName();
                   
                    JobDetailImpl jobDetail = new JobDetailImpl(jobName, null, QuartzJob.class);
                    jobDetail.getJobDataMap().put("async", new AsynchronousEvent(type, parameters));
                    String $null = null;
                    SimpleTriggerImpl trigger = new SimpleTriggerImpl(triggerName, $null);     
                    try
                    {
                      scheduler.scheduleJob(jobDetail, trigger);
                      return new QuartzTriggerHandle(triggerName);
                    }
                    catch (Exception se)
                    {
                      log.debug("Cannot Schedule a Quartz Job");
                      throw new RuntimeException(se);
                    }
                 }
                 
                 public QuartzTriggerHandle scheduleTimedEvent(String type, Schedule schedule, Object... parameters)
                 {
                    return scheduleWithQuartzServiceAndWrapExceptions( schedule, new AsynchronousEvent(type, parameters) );
                 }
                
                 public QuartzTriggerHandle scheduleInvocation(InvocationContext invocation, Component component)
                 {
                    return scheduleWithQuartzServiceAndWrapExceptions( createSchedule(invocation), new AsynchronousInvocation(invocation, component) );
                 }

                 private static Date calculateDelayedDate (long delay)
                 {
                    Date now = new Date ();
                    now.setTime(now.getTime() + delay);
                    return now;
                 }
                
                 private QuartzTriggerHandle scheduleWithQuartzServiceAndWrapExceptions(Schedule schedule, Asynchronous async)
                 {
                     try
                     {
                         return scheduleWithQuartzService(schedule, async);
                     }
                     catch (ParseException pe)
                     {
                         throw new RuntimeException(pe);
                     }
                     catch (SchedulerException se)
                     {
                         throw new RuntimeException(se);
                     }
                 }

                 private QuartzTriggerHandle scheduleWithQuartzService(Schedule schedule, Asynchronous async) throws SchedulerException, ParseException
                 {
                    String jobName = nextUniqueName();
                    String triggerName = nextUniqueName();
                   
                    JobDetailImpl jobDetail = new JobDetailImpl(jobName, null, QuartzJob.class);
                    jobDetail.getJobDataMap().put("async", async);

                    if (schedule instanceof CronSchedule)
                    {
                        CronSchedule cronSchedule = (CronSchedule) schedule;
                        CronTriggerImpl trigger = new CronTriggerImpl (triggerName, null);
                        trigger.setCronExpression(cronSchedule.getCron());
                        trigger.setEndTime(cronSchedule.getFinalExpiration());
                     
                        if ( cronSchedule.getExpiration()!=null )
                        {
                          trigger.setStartTime (cronSchedule.getExpiration());
                        }
                        else if ( cronSchedule.getDuration()!=null )
                        {
                          trigger.setStartTime (calculateDelayedDate(cronSchedule.getDuration()));
                        }
                     
                        scheduler.scheduleJob( jobDetail, trigger );
                    }
                    else if (schedule instanceof TimerSchedule)
                    {
                        TimerSchedule timerSchedule = (TimerSchedule) schedule;
                        if (timerSchedule.getIntervalDuration() != null)
                        {
                           if ( timerSchedule.getExpiration()!=null )
                           {
                              SimpleTriggerImpl trigger = new SimpleTriggerImpl(triggerName, null,
                                      timerSchedule.getExpiration(),
                                      timerSchedule.getFinalExpiration(),
                                      SimpleTriggerImpl.REPEAT_INDEFINITELY,
                                      timerSchedule.getIntervalDuration());
                              scheduler.scheduleJob( jobDetail, trigger );
                 
                           }
                           else if ( timerSchedule.getDuration()!=null )
                           {
                               SimpleTriggerImpl trigger = new SimpleTriggerImpl(triggerName, null,
                                       calculateDelayedDate(timerSchedule.getDuration()),
                                       timerSchedule.getFinalExpiration(), SimpleTriggerImpl.REPEAT_INDEFINITELY,
                                       timerSchedule.getIntervalDuration());
                               scheduler.scheduleJob( jobDetail, trigger );
                 
                           }
                           else
                           {
                              SimpleTriggerImpl trigger = new SimpleTriggerImpl(triggerName, null, new Date(),
                                      timerSchedule.getFinalExpiration(),
                                      SimpleTriggerImpl.REPEAT_INDEFINITELY,
                                      timerSchedule.getIntervalDuration());
                              scheduler.scheduleJob( jobDetail, trigger );
                 
                           }
                        }
                        else
                        {
                          if ( schedule.getExpiration()!=null )
                          {
                              SimpleTriggerImpl trigger = new SimpleTriggerImpl (triggerName, null, schedule.getExpiration());
                              scheduler.scheduleJob(jobDetail, trigger);
                 
                          }
                          else if ( schedule.getDuration()!=null )
                          {
                              SimpleTriggerImpl trigger = new SimpleTriggerImpl (triggerName, null,
                                      calculateDelayedDate(schedule.getDuration()));
                              scheduler.scheduleJob(jobDetail, trigger);
                 
                          }
                          else
                          {
                             String $null = null; 
                             SimpleTriggerImpl trigger = new SimpleTriggerImpl(triggerName, $null);
                             scheduler.scheduleJob(jobDetail, trigger);
                 
                          }
                        }
                    }
                    else
                    {
                        throw new IllegalArgumentException("unrecognized schedule type");
                    }

                    return new QuartzTriggerHandle(triggerName);
                 }
                
                 private String nextUniqueName ()
                 {
                    return (new UID()).toString();
                 }
                
                 @Destroy
                 public void destroy() throws SchedulerException
                 {
                    scheduler.shutdown();
                 }
                
                 public static class QuartzJob implements Job
                 {
                    private Asynchronous async;
                   
                    public QuartzJob() { }

                    public void execute(JobExecutionContext context)
                        throws JobExecutionException
                    {
                       JobDataMap dataMap = context.getJobDetail().getJobDataMap();
                       async = (Asynchronous)dataMap.get("async");
                      
                 
                       String $name = null;
                       if (  context.getTrigger() instanceof AbstractTrigger) {
                        $name = ( (AbstractTrigger)context.getTrigger() ).getName();
                       } else {
                        $name = context.getTrigger().getDescription();
                       }
                       QuartzTriggerHandle handle = new QuartzTriggerHandle($name);
                      
                       try
                       {
                          async.execute(handle);
                       }
                       catch (Exception e)
                       {
                          async.handleException(e, handle);
                       }
                    }
                 }

                 public Scheduler getScheduler()
                 {
                    return scheduler;
                 }
                


                 public static QuartzDispatcher instance()
                 {
                    return (QuartzDispatcher) AbstractDispatcher.instance();
                 }

              }

              • 4. Re: latest version of Quartz that will work with Seam 2.2
                Roger Mori Newbie

                My previous email has a typo:

                 

                It should say:

                 

                [...] replace the Quartzdispatcher provided with seam with the one listed below.

                 

                and not :

                 

                [...] replace the Quartzdispatcher listed below with the one provided with seam.