2012-07-20 2 views
0

ServletContextListener를 구현하는 Servlet을 사용하여 strut2 웹 응용 프로그램에 QuartzFramework를 추가했습니다. 석영 속성을 사용하는 서블릿에서 저는 "AsyncJobsQuartz"라고하는 이름으로 Quartz 인스턴스를 만들고 scheduler.start()를 사용하여 시작했습니다.Java Quartz Scheduler 내 구성에 대한 버그 또는 문제

예약 된 JOBS는 JobStore를 사용하므로 예약 된 시간에 매일 작업이 실행됩니다. 하지만 문제는 작업이 실행 중일 때입니다. 다른 곳에서는 스케줄러 인스턴스를 사용할 수 없습니다. 즉, 다른 행동에 내가

scheduler = schedulerFactory.getScheduler("ASYNC_JOBS_SCHEDULER"); 

를 사용하여 인스턴스를 얻기 위해 노력하고 있어요 그러나) 스피 점점 스케줄러로서 null 이후 scheduler.getJobGroupNames는 (널 포인터 예외입니다. 그러나 작업이 끝나자 마자 모든 세부 사항이 포함 된 스케줄러가 돌아옵니다.

나는 혼란 스럽다. 내가 설정을 놓쳤거나 Quartz에 버그가 있는지. 해결책을 제공해주십시오.

스케줄러를 인스턴스화하고 시작하는 클래스 (서블릿). 내가 지침에 따라 한 번 이상, 즉 hibernate.cfg.xml에서 quartz.properties에서 db 자격 증명을 지정하지 않기 때문에 quartz.properties 파일을 사용하지 않습니다.

package com.generalsentiment.test.quartz; 

import static org.quartz.CronScheduleBuilder.cronSchedule; 
import static org.quartz.JobBuilder.newJob; 
import static org.quartz.TriggerBuilder.newTrigger; 

import java.lang.reflect.Field; 
import java.sql.Driver; 
import java.sql.DriverManager; 
import java.sql.SQLException; 
import java.util.Date; 
import java.util.List; 
import java.util.Map; 
import java.util.Properties; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import com.google.common.collect.Maps; 
import org.apache.commons.configuration.Configuration; 
import org.apache.commons.configuration.PropertiesConfiguration; 
import org.apache.commons.configuration.ConfigurationException; 

import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 

import org.hibernate.SessionFactory; 
import org.hibernate.impl.SessionFactoryImpl; 
import org.quartz.CronTrigger; 
import org.quartz.JobDetail; 
import org.quartz.JobKey; 
import org.quartz.Scheduler; 
import org.quartz.SchedulerException; 
import org.quartz.SchedulerMetaData; 
import org.quartz.impl.matchers.GroupMatcher; 

import com.generalsentiment.util.HibernateUtil; 
import com.generalsentiment.util.quartz.SchedulerConstants; 
import com.generalsentiment.util.quartz.QuartzSchedulerUtil; 
import org.apache.commons.configuration.*; 

public class QuartzServlet implements ServletContextListener { 

    private Map<String, String> existingJobsList; 
    private String hibernateConnectionUrl; 
    private SessionFactory sessionFactory; 

    @Override 
    public void contextInitialized(ServletContextEvent sce) { 
     try { 
      Properties properties = new Properties(); 
      Field f = SessionFactoryImpl.class.getDeclaredField("properties"); 
      f.setAccessible(true); 
      sessionFactory = HibernateUtil.getSessionFactory(); 

      Properties p = (Properties) f.get(sessionFactory); 
      properties.setProperty("org.quartz.scheduler.instanceName", SchedulerConstants.SCHEDULER_INSTANCE_NAME); 
      properties.setProperty("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); 
      properties.setProperty("org.quartz.threadPool.threadCount", "4"); 
      properties.setProperty("org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread", "true"); 

      properties.setProperty("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreCMT"); 
      properties.setProperty("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate"); 
      properties.setProperty("org.quartz.jobStore.useProperties", "false"); 
      properties.setProperty("org.quartz.jobStore.dataSource", "tasksDataStoreContainer"); 
      properties.setProperty("org.quartz.jobStore.nonManagedTXDataSource", "tasksDataStoreQuartz"); 
      properties.setProperty("org.quartz.jobStore.tablePrefix", "QRTZ_"); 
      properties.setProperty("org.quartz.jobStore.misfireThreshold", "60000"); 
      properties.setProperty("org.quartz.jobStore.isClustered", "false"); 

      properties.setProperty("org.quartz.dataSource.tasksDataStoreContainer.driver", p.getProperty("hibernate.connection.driver_class")); 
      properties.setProperty("org.quartz.dataSource.tasksDataStoreContainer.URL", p.getProperty("hibernate.connection.url")); 
      properties.setProperty("org.quartz.dataSource.tasksDataStoreContainer.user", p.getProperty("hibernate.connection.username")); 
      properties.setProperty("org.quartz.dataSource.tasksDataStoreContainer.password", p.getProperty("hibernate.connection.password")); 
      properties.setProperty("org.quartz.dataSource.tasksDataStoreContainer.maxConnections", "20"); 

      properties.setProperty("org.quartz.dataSource.tasksDataStoreQuartz.driver", p.getProperty("hibernate.connection.driver_class")); 
      properties.setProperty("org.quartz.dataSource.tasksDataStoreQuartz.URL", p.getProperty("hibernate.connection.url")); 
      properties.setProperty("org.quartz.dataSource.tasksDataStoreQuartz.user", p.getProperty("hibernate.connection.username")); 
      properties.setProperty("org.quartz.dataSource.tasksDataStoreQuartz.password", p.getProperty("hibernate.connection.password")); 
      properties.setProperty("org.quartz.dataSource.tasksDataStoreQuartz.maxConnections", "20"); 
      hibernateConnectionUrl = p.getProperty("hibernate.connection.url"); 


      System.out.println("THE APPLICATION STARTED"); 

      // First we must get a reference to a scheduler 
      existingJobsList = Maps.newHashMap(); 
      Scheduler scheduler = QuartzSchedulerUtil.initiateSchedulerFactory(properties); 
      System.out.println("------- Initialization Complete --------"); 
      System.out.println("------- Scheduling Jobs ----------------"); 

      System.out.println("------- Starting Scheduler ----------------"); 
      List<String> jobGroupNames = scheduler.getJobGroupNames(); 
      for (String current : jobGroupNames) { 
       for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.<JobKey>groupEquals(current))) { 
        existingJobsList.put(jobKey.getName(), jobKey.getGroup()); 
       } 
      } 

      if (!existingJobsList.containsKey("ExportOrgUsersToFileJob")) { 

       JobDetail job = newJob(ExportOrgUsersToFileJob.class).withIdentity("ExportOrgUsersToFileJob", 
         SchedulerConstants.JOBS_GROUP).build(); 

       CronTrigger trigger = newTrigger().withIdentity("[email protected]", 
         SchedulerConstants.TRIGGER_MORNING_GROUP).withSchedule(cronSchedule("00 10 15 * * ?")).build(); 
       job.getJobDataMap().put("jobDescription", "Exports a particular Organization users to file"); 
       job.getJobDataMap().put("jobStatus", SchedulerConstants.JOB_STATUS.PENDING); 
       Date ft = scheduler.scheduleJob(job, trigger); 
      } 

      if (!existingJobsList.containsKey("DownloadScoresJob")) { 
       JobDetail job1 = newJob(DownloadScoresJob.class).withIdentity("DownloadScoresJob", 
         SchedulerConstants.JOBS_GROUP).build(); 

       CronTrigger trigger1 = newTrigger().withIdentity("[email protected]", 
         SchedulerConstants.TRIGGER_EVENING_GROUP).withSchedule(cronSchedule("00 15 15 * * ?")).build(); 

       job1.getJobDataMap().put("jobDescription", "Downloads involvement index scores for given synsets"); 
       job1.getJobDataMap().put("jobStatus", SchedulerConstants.JOB_STATUS.PENDING); 
       Date ft1 = scheduler.scheduleJob(job1, trigger1); 
      } 
      //   JobListener jobListener = new QuartzJobListener(); 
      //   scheduler.getListenerManager().addJobListener(jobListener, allJobs()); 

      scheduler.start(); 

      System.out.println("------- Started Scheduler -----------------"); 

      SchedulerMetaData metaData = scheduler.getMetaData(); 
      System.out.println("Executed " + metaData.getNumberOfJobsExecuted() + " jobs."); 
     } catch (IllegalAccessException ex) { 
      Logger.getLogger(QuartzServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (NoSuchFieldException ex) { 
      Logger.getLogger(QuartzServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (SecurityException ex) { 
      Logger.getLogger(QuartzServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (SchedulerException se) { 
      System.out.println(se); 
     } catch (ConfigurationException ex) { 
      Logger.getLogger(QuartzServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } 

    } 

    @Override 
    public void contextDestroyed(ServletContextEvent sce) { 
     try { 
      Scheduler scheduler = QuartzSchedulerUtil.getCurrentScheduler(); 
      if (scheduler != null) { 
       //to avoid NPE 
       scheduler.shutdown(true); 
      } 
      Thread.sleep(1000); 
      Driver mySqlDriver = DriverManager.getDriver(hibernateConnectionUrl); 
      DriverManager.deregisterDriver(mySqlDriver); 
      sessionFactory.close(); 
     } catch (SchedulerException ex) { 
      Logger.getLogger(QuartzServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(QuartzServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (SQLException ex) { 
      Logger.getLogger(QuartzServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     System.out.println("THE QUARTZ APPLICATION STOPPED"); 
    } 

    public String getHibernateConnectionUrl() { 
     return hibernateConnectionUrl; 
    } 

    public void setHibernateConnectionUrl(String hibernateConnectionUrl) { 
     this.hibernateConnectionUrl = hibernateConnectionUrl; 
    } 
} 
+1

당신이 당신의 quartz.properties이 파일을 보일 수 있는가? 스케줄러는 여러 작업을 실행하기 위해 쓰레드가 필요하며 풀에서 원하는 쓰레드의 수를 알려주고 싶습니다. 질문 게시판에 –

+0

코드를 추가했습니다. –

답변

1

저는 Quartz v1.8.4와 Struts2를 사용하고 있습니다. 내 작업 중 하나에서 스케줄러에 액세스하려면 다음을 사용해야했습니다.

public Scheduler getScheduler() throws SchedulerException { 
    ServletContext context = this.getServletRequest().getSession().getServletContext(); 
    SchedulerFactory factory = (StdSchedulerFactory) context.getAttribute("org.quartz.impl.StdSchedulerFactory.KEY"); 
    return factory.getScheduler(); 
} 

내 프로젝트에서 내가 가진 석영 항아리 석영-1.8.4.jar 및 석영 - 오라클-1.8.4.jar입니다.

나는 석영은 단순히 web.xml 파일에 정의가 제공하는 서블릿을 사용하여 초기화 :

<servlet> 
    <servlet-name>QuartzInitializer</servlet-name> 
    <servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class> 
    <init-param> 
    <param-name>shutdown-on-unload</param-name> 
    <param-value>true</param-value> 
    </init-param> 
    <load-on-startup>2</load-on-startup> 
</servlet> 
관련 문제