title: Quartz Scheduler : Failed to obtain DB connection from data source
body: <p>I trying to implement <code>Quartz-Scheduler</code> in <code>Spring-Boot</code> application. </p>
  
  <p>But when I'm trying to schedule job, I'getting this exception:</p>
  
  <pre><code>2017-03-21 15:57:42.817  INFO 12069 --- [o-8080-exec-178] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler 'QuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties'
  2017-03-21 15:57:42.817  INFO 12069 --- [o-8080-exec-178] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler version: 2.2.1
  org.quartz.SchedulerConfigException: Failure occured during job recovery. [See nested exception: org.quartz.JobPersistenceException: Failed to obtain DB connection from data source 'myDs': java.sql.SQLException: There is no DataSource named 'myDs' [See nested exception: java.sql.SQLException: There is no DataSource named 'myDs']]
      at org.quartz.impl.jdbcjobstore.JobStoreSupport.schedulerStarted(JobStoreSupport.java:692)
      at org.quartz.core.QuartzScheduler.start(QuartzScheduler.java:567)
      at org.quartz.impl.StdScheduler.start(StdScheduler.java:142)
      at com.example.controller.StudentController.getAllStudents(StudentController.java:62)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
      at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
      at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
      at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
      at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
      at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
      at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
      at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115)
      at org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:59)
      at org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:90)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
      at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784)
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410)
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:745)
  Caused by: org.quartz.JobPersistenceException: Failed to obtain DB connection from data source 'myDs': java.sql.SQLException: There is no DataSource named 'myDs' [See nested exception: java.sql.SQLException: There is no DataSource named 'myDs']
      at org.quartz.impl.jdbcjobstore.JobStoreSupport.getConnection(JobStoreSupport.java:778)
      at org.quartz.impl.jdbcjobstore.JobStoreTX.getNonManagedTXConnection(JobStoreTX.java:71)
      at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3784)
      at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverJobs(JobStoreSupport.java:834)
      at org.quartz.impl.jdbcjobstore.JobStoreSupport.schedulerStarted(JobStoreSupport.java:690)
      ... 65 more
  Caused by: java.sql.SQLException: There is no DataSource named 'myDs'
      at org.quartz.utils.DBConnectionManager.getConnection(DBConnectionManager.java:104)
      at org.quartz.impl.jdbcjobstore.JobStoreSupport.getConnection(JobStoreSupport.java:775)
      ... 69 more
  </code></pre>
  
  <p>quartz.properties:</p>
  
  <pre><code>#============================================================================
  # Configure Main Scheduler Properties
  #============================================================================
  
  org.quartz.scheduler.instanceId = AUTO
  org.quartz.scheduler.makeSchedulerThreadDaemon = true
  
  #============================================================================
  # Configure ThreadPool
  #============================================================================
  
  org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
  org.quartz.threadPool.makeThreadsDaemons = true
  org.quartz.threadPool.threadCount: 20
  org.quartz.threadPool.threadPriority: 5
  
  #============================================================================
  # Configure JobStore
  #============================================================================
  
  org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX 
  org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
  org.quartz.jobStore.dataSource = myDs
  org.quartz.jobStore.tablePrefix = QRTZ_
  org.quartz.jobStore.isClustered = false
  org.quartz.jobStore.dataSource = myDs
  org.quartz.jobStore.misfireThreshold = 25000
  
  
  #============================================================================
  # Configure DataSources  
  #============================================================================
  
  org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
  org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/quartz
  org.quartz.dataSource.myDS.user = root
  org.quartz.dataSource.myDS.password = root
  org.quartz.dataSource.myDS.maxConnections = 5
  org.quartz.dataSource.myDS.validationQuery = select 1
  </code></pre>
  
  <p>I do have a database named quartz and all the quartz tables loaded into it.</p>
  
  <p>application.properties:</p>
  
  <pre><code>#disbale Spring banner
  spring.main.banner-mode=off
  
  # Loads SQL scripts? schema.sql and data.sql
  #spring.datasource.initialize=true
  
  spring.datasource.url=jdbc:mysql://localhost:3306/career_focus
  spring.datasource.username=root
  spring.datasource.password=root
  spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  
  quartz.enabled=true
  
  # HikariCP settings
  # spring.datasource.hikari.*
  
  #60 sec
  spring.datasource.hikari.connection-timeout=60000
  # max 5
  spring.datasource.hikari.maximum-pool-size=5
  </code></pre>
  
  <p>This is how I'm trying to Schedule a job:</p>
  
  <pre><code>JobDetail detail = JobBuilder.newJob().ofType(JobRunner.class).withIdentity("jobName123", "jobGroup123")
              .storeDurably().withDescription("Invoke Sample Job service...").build();
  
  String cronExpr = "0/10 * * * * ?";
  try {
      Scheduler scheduler = new StdSchedulerFactory().getScheduler();
      Trigger trigger = TriggerBuilder.newTrigger()
              .withIdentity("trigger3", "group1")
              .withSchedule(CronScheduleBuilder.cronSchedule(cronExpr))
              .forJob("jobName123", "jobGroup123")
              .build();
      scheduler.start();
      scheduler.scheduleJob(detail, trigger);
  } catch (SchedulerException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
  }
  </code></pre>
  
  <p><strong>EDIT:</strong></p>
  
  <p>SchedulerConfig.java</p>
  
  <pre><code>@Configuration
  @ConditionalOnProperty(name = "quartz.enabled")
  public class SchedulerConfig {
      //
      // @Autowired
      // List&lt;Trigger&gt; listOfTrigger;
  
      @Bean
      public JobFactory jobFactory(ApplicationContext applicationContext) {
          AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
          jobFactory.setApplicationContext(applicationContext);
          return jobFactory;
      }
  
      @Bean
      public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource, JobFactory jobFactory) throws IOException {
          SchedulerFactoryBean factory = new SchedulerFactoryBean();
          factory.setOverwriteExistingJobs(true);
          factory.setAutoStartup(true);
          factory.setDataSource(dataSource);
          factory.setJobFactory(jobFactory);
          factory.setQuartzProperties(quartzProperties());
          // Here we will set all the trigger beans we have defined.
          // if (!AppUtil.isObjectEmpty(listOfTrigger)) {
          // factory.setTriggers(listOfTrigger.toArray(new
          // Trigger[listOfTrigger.size()]));
          // }
  
          return factory;
      }
  
      @Bean
      public Properties quartzProperties() throws IOException {
          PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
          propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
          propertiesFactoryBean.afterPropertiesSet();
          return propertiesFactoryBean.getObject();
      }
  
      public static SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long pollFrequencyMs) {
          SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
          factoryBean.setJobDetail(jobDetail);
          factoryBean.setStartDelay(0L);
          factoryBean.setRepeatInterval(pollFrequencyMs);
          factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
          // in case of misfire, ignore all missed triggers and continue :
          factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
          return factoryBean;
      }
  
      // Use this method for creating cron triggers instead of simple triggers:
      public static CronTriggerFactoryBean createCronTrigger(JobDetail jobDetail, String cronExpression) {
          CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
          factoryBean.setJobDetail(jobDetail);
          factoryBean.setCronExpression(cronExpression);
          factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
          return factoryBean;
      }
  
      public static JobDetailFactoryBean createJobDetail(Class jobClass) {
          JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
          factoryBean.setJobClass(jobClass);
          // job has to be durable to be stored in DB:
          factoryBean.setDurability(true);
          return factoryBean;
      }
  
  }
  </code></pre>
  
  <p>AutowiringSpringBeanJobFactory.java </p>
  
  <pre><code>public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements
          ApplicationContextAware {
  
      private transient AutowireCapableBeanFactory beanFactory;
  
      @Override
      public void setApplicationContext(final ApplicationContext context) {
          beanFactory = context.getAutowireCapableBeanFactory();
      }
  
      @Override
      protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
          final Object job = super.createJobInstance(bundle);
          beanFactory.autowireBean(job);
          return job;
      }
  }
  </code></pre>