JDBCJobStore Confusion in Quartz Schdular - java

I am using Quartz JDBCJobStore and have following job definition
JobDetail job=newJob(HelloJob.class).withIdentity("demo11", "group11").
usingJobData("jobSays", "Hello Vikas")
.usingJobData("myFloatValue", 3.141f).storeDurably(true).
build();
and trigger as
Trigger trigger=newTrigger().withIdentity("Trigger11","group11")
.startNow().withSchedule(CronScheduleBuilder.
cronSchedule("0 0/1 * * * ?")).build();
I was of impression that Quartz will store jobSays and myFloatValue in the database but I am unable see any such property in the database.
Is there a way to store these JobData in the database?
Here is the quartz.property file
org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.dataSource = myDS
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.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.MSSQLDelegate
org.quartz.jobStore.tablePrefix = QRTZ_

Quartz stores job data as BLOB datatype in QRTZ_JOB_DETAILS table.
Please check there.

Related

What happens if I do not shutdown() quartz scheduler

What would happen if I do not call the shutdown() method on my Quartz scheduler?
I have a job that needs to be run each day at different times the day:
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
JobDetail job = newJob(NotificationCronJob.class).withIdentity("notificationJob1", "notificationGroup1").build();
CronTrigger cronTriggerSunday = newTrigger().withIdentity("notificationTrigger1", "notificationGroup1")
.withSchedule(cronSchedule(Config.SUNDAY_NOTIFY))
.forJob(job)
.build();
CronTrigger cronTriggerMonday = newTrigger().withIdentity("notificationTrigger2", "notificationGroup1")
.withSchedule(cronSchedule(Config.MONDAY_NOTIFY))
.forJob(job)
.build();
CronTrigger cronTriggerTuesday = newTrigger().withIdentity("notificationTrigger3", "notificationGroup1")
.withSchedule(cronSchedule(Config.TUESDAY_NOTIFY))
.forJob(job)
.build();
CronTrigger cronTriggerWednesday = newTrigger().withIdentity("notificationTrigger4", "notificationGroup1")
.withSchedule(cronSchedule(Config.WEDENSDAY_NOTIFY))
.forJob(job)
.build();
CronTrigger cronTriggerThursday = newTrigger().withIdentity("notificationTrigger5", "notificationGroup1")
.withSchedule(cronSchedule(Config.THURSDAY_NOTIFY))
.forJob(job)
.build();
CronTrigger cronTriggerFriday = newTrigger().withIdentity("notificationTrigger6", "notificationGroup1")
.withSchedule(cronSchedule(Config.FRIDAY_NOTIFY))
.forJob(job)
.build();
CronTrigger cronTriggerSaturday = newTrigger().withIdentity("notificationTrigger7", "notificationGroup1")
.withSchedule(cronSchedule(Config.SATURDAY_NOTIFY))
.forJob(job)
.build();
scheduler.scheduleJob(job, cronTriggerSunday);
scheduler.scheduleJob(cronTriggerMonday);
scheduler.rescheduleJob(cronTriggerMonday.getKey(), cronTriggerMonday);
scheduler.scheduleJob(cronTriggerTuesday);
scheduler.scheduleJob(cronTriggerWednesday);
scheduler.scheduleJob(cronTriggerThursday);
scheduler.scheduleJob(cronTriggerFriday);
scheduler.scheduleJob(cronTriggerSaturday);
scheduler.start();
Each Config.DAY is a cron expression fore example 0 0 9 ? * 1 run each sunday at 9am.
Now the problem is if I shutdown the scheduler the job would never be run, so therefore I just start it and just let it run. But I am concerned with if that would result in some memory leak og threading problem of some kind, I cannot figure out if this is a well enough solution. My quartz properties are as follows:
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.MSSQLDelegate
org.quartz.jobStore.dataSource = myDS
org.quartz.dataSource.myDS.driver = com.microsoft.sqlserver.jdbc.SQLServerDriver
org.quartz.dataSource.myDS.URL = jdbc:sqlserver://localhost;databaseName=myDB
org.quartz.dataSource.myDS.user = myUser
org.quartz.dataSource.myDS.password = myPassword
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.jobStore.tablePrefix = QRTZ_
What I need to achieve in the end is an application that runs a job at the defined times and the scheduling should be mutable without restarting the application.
Quartz scheduler shouldn't call 'shutdown' method while your application is running. If you found any problem such as memory leak, you can issue the problem to Quartz community.
If 'shutdown' is called, Quartz scheduler is never restarted even if you call 'start' method again.
Please refer to the below URL which is Quartz documentation.
http://www.quartz-scheduler.org/documentation/quartz-2.x/cookbook/ShutdownScheduler.html

how to reschedule quartz job dynamically

I am trying to update the quartz job scheduling dynamically:
Initially it is after every 3 minute, but dynamically i want to make it 1 min.
here's my quartz.xml and java file
quartz.xml
<schedule>
<job>
<name>JOBNAME</name>
<group>GroupDummy</group>
<description>This is Job B</description>
<job-class>in.xyz.MyClass.java</job-class>
</job>
<trigger>
<cron>
<name>dummyTriggerNameB</name>
<group>MYTRIGGER_GROUP</group>
<job-name>JOBNAME</job-name>
<job-group>GroupDummy</job-group>
<cron-expression>0 0/3 * * * ?</cron-expression>
</cron>
</trigger>
</schedule>
MyClass.java
public void execute(JobExecutionContext arg0) throws JobExecutionException {
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger("dummyTriggerNameB", "MYTRIGGER_GROUP");
CronExpression cronExpression = new CronExpression("0 0/1 * * * ?");
cronTrigger.setCronExpression(cronExpression);
scheduler.rescheduleJob("dummyTriggerNameB", "MYTRIGGER_GROUP", cronTrigger);
}
I am trying the above java code to change the time from 3 minute to 1 minute dynamically but it is not happening "cronTrigger" is returning null.
Help to solve this problem so that i can reschedule dynamically.

quartz job run only once

I have created Job. I want to run it every minute
but it run only once.
following is my java class
String exp = "0 0/1 * 1/1 * ? *";
SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();
scheduler.start();
JobDetail job = JobBuilder.newJob(schedulartest.class).build();
Trigger trigger = TriggerBuilder.newTrigger()
.startNow()
.withSchedule(
CronScheduleBuilder.cronSchedule(exp))
.build();
scheduler.scheduleJob(job, trigger);
when i execute it it run only first time.
can someone help to figure out these
This is how you should do it :
CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule( "* * * * * ?" );
Trigger trigger = TriggerBuilder.newTrigger().withIdentity( "trigger-" + id, group ).withSchedule( cronSchedule ).build();
scheduler.scheduleJob( job, trigger );

Two instances not doing automatic load balancing in Quartz scheduler on the same machine

Two instances in a clustered JobStore are not working on the same machine inspite of having the correct quartz properties (As given in the docs).
The problem seems that the load balancing is not happening and everytime it's the same instance that picks the job (The one that starts later).
============================================================================
Configure Main Scheduler Properties
org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = instance1
============================================================================
Configure ThreadPool
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5
============================================================================
Configure JobStore
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = mySQLDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 1000
============================================================================
Configure Datasources
org.quartz.dataSource.mySQLDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.mySQLDS.URL = jdbc:mysql://localhost:3306/quartz2
org.quartz.dataSource.mySQLDS.user = quartz2
org.quartz.dataSource.mySQLDS.password = quartz2123
org.quartz.dataSource.mySQLDS.maxConnections = 5
org.quartz.dataSource.mySQLDS.validationQuery=select 0 from dual
The other instance had instance id as instance2.

quartz.properties cant access mysql : Could not load driverClass com.mysql.jdbc.Driver

i am struggling to resolve this matter, i have try to run a small test to connect with my mysql and it work.but when i am trying to work with quartz.properties it cannot access mysql.
i am sure my jdbc mysql driver is fine. as other than using quartz.properties, i can access my mysql database.
i need help. i have work on this for days now.
here is the part i suspect have problem
#The details of the datasource specified previously
org.quartz.dataSource.myDS.driver =com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL =jdbc:mysql://10.1.1.111:3306/somedatabase
org.quartz.dataSource.myDS.user =username
org.quartz.dataSource.myDS.password =somepassword
org.quartz.dataSource.myDS.maxConnections = 20
error output:
207 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'MyScheduler' initialized from default file in current working dir: 'quartz.properties'
208 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.2.1
267 [main] DEBUG com.mchange.v2.resourcepool.BasicResourcePool - incremented pending_acquires: 1
267 [main] DEBUG com.mchange.v2.resourcepool.BasicResourcePool - incremented pending_acquires: 2
268 [main] DEBUG com.mchange.v2.resourcepool.BasicResourcePool - incremented pending_acquires: 3
268 [main] DEBUG com.mchange.v2.resourcepool.BasicResourcePool - com.mchange.v2.resourcepool.BasicResourcePool#42af94c4 config: [start -> 3; min -> 1; max -> 20; inc -> 3; num_acq_attempts -> 30; acq_attempt_delay -> 1000; check_idle_resources_delay -> 0; mox_resource_age -> 0; max_idle_time -> 0; excess_max_idle_time -> 0; destroy_unreturned_resc_time -> 0; expiration_enforcement_delay -> 0; break_on_acquisition_failure -> false; debug_store_checkout_exceptions -> false]
269 [com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2] WARN com.mchange.v2.c3p0.DriverManagerDataSource - Could not load driverClass com.mysql.jdbc.Driver
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
Here is my quartz code
public class QuartzDaily {
static Logger log = Logger.getLogger("QuartzDaily");
public static void main(String[] args) throws ParseException, SchedulerException, IOException, NoSuchAlgorithmException
{
//lines of codes to configure log
DateFormat format3 = new SimpleDateFormat( "MM_dd_yyyy_HH_mm" );
Date dateToday = new Date();
String strToday= format3.format(dateToday);
BasicConfigurator.configure();
PatternLayout pattern = new PatternLayout("%r [%t] %-5p %c %x - %m%n");
FileAppender fileappender = new FileAppender(pattern,"log\\QuartzScheduler_"+strToday+".txt");
log.addAppender(fileappender);
log.info("QuartzReport; main(): [** Starting scheduler services **]");
//run quartz job
quartzWeekly();
}
public static void quartzWeekly() throws SchedulerException{
//some quartz job code
}
public static class TestJob implements Job {
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("hello world");
}
}
}
Below is the full code, below code is not mine, it was taken from random tutorial site.
#Skip Update Check
#Quartz contains an "update check" feature that connects to a server to
#check if there is a new version of Quartz available
org.quartz.scheduler.skipUpdateCheck: true
org.quartz.scheduler.instanceName =MyScheduler
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 4
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.threadPool.threadPriority = 5
#specify the jobstore used
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = false
#specify the TerracottaJobStore
#org.quartz.jobStore.class = org.terracotta.quartz.TerracottaJobStore
#org.quartz.jobStore.tcConfigUrl = localhost:9510
#The datasource for the jobstore that is to be used
org.quartz.jobStore.dataSource = myDS
#quartz table prefixes in the database
org.quartz.jobStore.tablePrefix = qrtz_
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.isClustered = false
#The details of the datasource specified previously
org.quartz.dataSource.myDS.driver =com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL =jdbc:mysql://10.1.1.11:3306/somedatabase
org.quartz.dataSource.myDS.user =username
org.quartz.dataSource.myDS.password =somepassword
org.quartz.dataSource.myDS.maxConnections = 20
#Clustering
#clustering currently only works with the JDBC-Jobstore (JobStoreTX
#or JobStoreCMT). Features include load-balancing and job fail-over
#(if the JobDetail's "request recovery" flag is set to true). It is important to note that
# When using clustering on separate machines, make sure that their clocks are synchronized
#using some form of time-sync service (clocks must be within a second of each other).
#See http://www.boulder.nist.gov/timefreq/service/its.htm.
# Never fire-up a non-clustered instance against the same set of tables that any
#other instance is running against.
# Each instance in the cluster should use the same copy of the quartz.properties file.
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
#Each server must have the same copy of the configuration file.
#auto-generate instance ids.
org.quartz.scheduler.instanceId = AUTO
#Note :
#If a job throws an exception, Quartz will typically immediately
#re-execute it (and it will likely throw the same exception again).
#It's better if the job catches all exception it may encounter, handle them,
#and reschedule itself, or other jobs. to work around the issue.
I had the exact same issue and I fixed it by adding mysql connector jar in WEB-INF/lib. Please make sure that the WEB-INF is marked as a source folder in build path.

Categories

Resources