I am new to web development I am making some web services using java servlets, and I am stuck in so many How to do it? stuff :(
I am developing an application in which I need to reset the mysql table column values back to default values at some time let's say we need to reset the counter # every Sunday 10:00 pm.
is there any thing like alarm manager in Java or mysql that can run all the time in background and trigger # specific time.
Thanks,
Java has a good interface ScheduledExecutorService.
You can try this code
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
//every day to execute
long everyDayDelay = 24*60*60*1000;
//first time to execute, it can be your special date
//for example 5 seconds after launch
long timeToExecute = System.currentTimeMillis()+5*1000;
service.scheduleWithFixedDelay(new Task(), getTimeToLaunch(timeToExecute), everyDayDelay, TimeUnit.MILLISECONDS);
where
//return difference between now and timeToExecute
public static long getTimeToLaunch(long timeToExecute){
long current = System.currentTimeMillis();
return timeToExecute - current;
}
class Task implements Runnable{
#Override
public void run() {
System.out.println("Run task!");
}
}
UPDATE: Class to execute your sql-tasks
public class SqlExecutionService1 {
public static final long everyDayDelay = 24*60*60*1000;
public SqlExecutionService1(){
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
//every day to execute
//first time to execute
//for example 5 seconds after launch
long timeToExecute = System.currentTimeMillis()+5*1000;
service.scheduleWithFixedDelay(new SqlTask1(), getTimeToLaunch(timeToExecute), everyDayDelay, TimeUnit.MILLISECONDS);
}
private long getTimeToLaunch(long timeToExecute){
long current = System.currentTimeMillis();
return timeToExecute - current;
}
}
class SqlTask1 implements Runnable{
#Override
public void run() {
//your sql tasks
}
}
To create this class, when your app server starts - use method init() in one of your main servlets.
Example -
public class MainInitServlet extends HttpServlet {
public void init() {
new SqlExecutionService1();
}
}
The Data of a Database should be the basis for calculation, not the result of calculations. In example Bills wont ever be successfully revised.
I guess this fact will ever be a clash between Programmers and Architects.
you might also use the event scheduling mechanism of mysql
this depends on the version of mysql and whether it is enabled or not
is there any thing like alarm manager in Java or mysql that can run all the time in background and trigger # specific time.
look at a API called Quartz , where your program can schedule Jobs and it will run it at that time.
use method execute(JobExecutionContext jobExecution) use to fire trigger.
EG:
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
// Retrieve scheduler
Scheduler scheduler = null;
try {
scheduler = schedulerFactory.getScheduler();
}
catch (SchedulerException e) {
e.printStackTrace();
}
//this is a job
JobDetail job = new JobDetail("jobDetail", "jobDetailGroup", ImplementedJob.class);
SimpleTrigger trigger = new SimpleTrigger("Trigger Name","defaultGroup", DATE);
// schedule
scheduler.scheduleJob(job, trigger);
// start the scheduler
scheduler.start();
Related
In the spring boot app, I have to call a method for a given frequency.This frequency will be read from the database. Frequent could be seconds or minutes or hours or days, etc. How do I implement this schedule for spring boot?
To give more other alternative solutions beside #Scheduled annotation.
You can use ScheduledExecutorService to execute task with fixed rate or fixed delay.
ScheduledExecutorService executorService = Executors
.newSingleThreadScheduledExecutor();
Then you can use below function which depend on your need:
scheduleAtFixedRate
scheduleWithFixedDelay
Example:
Future<String> resultFuture =
executorService.schedule(callableTask, 1, TimeUnit.SECONDS);
Future<String> resultFuture = service
.scheduleAtFixedRate(runnableTask, 100, 450, TimeUnit.MILLISECONDS);
service.scheduleWithFixedDelay(task, 100, 150, TimeUnit.MILLISECONDS);
Refer:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html
https://www.baeldung.com/java-executor-service-tutorial
PS: i highly recommend quartz framework also, it can schedule task with many different policies.
for this you can use a cron with this annoation #Scheduled
Spring will schedule the annotated method to run at 10:15 AM on the 15th day of every month
#Scheduled(cron = "0 15 10 15 * ?")
public void scheduleTaskUsingCronExpression() {
long now = System.currentTimeMillis() / 1000;
System.out.println(
"schedule tasks using cron jobs - " + now);
}
see this doc https://spring.io/guides/gs/scheduling-tasks/
and this https://spring.io/guides/gs/scheduling-tasks/
In Order to get the cron exp from the db :
see this How to change Spring's #Scheduled fixedDelay at runtime?
You may use Task Exection and Sceduling API of Spring.
Your task to run in a scheduled mode
public class MyTask implements Runnable {
public void run(){
System.out.println("MyTask is running");
}
}
A service to be used for dynamically creation of sceduled jobs.
Inspired by this so answer.
You may add it in your library.
#Component
public class DbScheduledJobs {
private final TaskScheduler executor;
#Autowired
public DbScheduledJobs(TaskScheduler taskExecutor) {
this.executor = taskExecutor;
}
public void schedule(final Runnable task, String cronLike) {
executor.schedule(task, new CronTrigger(cronLike));
}
public void schedule(final Runnable task, LocalDateTime runOnceAt) {
executor.schedule(task, Date.from(runAt.atZone(ZoneId.systemDefault()).toInstant()));
}
public void schedulingExamples(final Runnable task) {
// Schedule a task to run once at the given date (here in 1minute)
executor.schedule(task, Date.from(LocalDateTime.now().plusMinutes(1)
.atZone(ZoneId.systemDefault()).toInstant()));
// Schedule a task that will run as soon as possible and every 1000ms
executor.scheduleAtFixedRate(task, 1000);
// Schedule a task that will first run at the given date and every 1000ms
executor.scheduleAtFixedRate(task, Date.from(LocalDateTime.now().plusMinutes(1)
.atZone(ZoneId.systemDefault()).toInstant()), 1000);
// Schedule a task that will run as soon as possible and every 1000ms after the previous completion
executor.scheduleWithFixedDelay(task, 1000);
// Schedule a task that will run as soon as possible and every 1000ms after the previous completion
executor.scheduleWithFixedDelay(task, Date.from(LocalDateTime.now().plusMinutes(1)
.atZone(ZoneId.systemDefault()).toInstant()), 1000);
// Schedule a task with the given cron expression
executor.schedule(task, new CronTrigger("*/5 * * * * MON-FRI"));
}
}
Your actual service, which reads from Db.
#Service
public class DbService {
private final DbScheduledJobs dbScheduledJobs;
#Autowired
public DbService(DbScheduledJobs dbScheduledJobs) {
this.dbScheduledJobs = dbScheduledJobs;
}
public void example() {
// Read your cron like schedule from db
String cronLikeScedule = "fetched from db"; // Ex. "*/5 * * * * MON-FRI"
// Choose your Runnable instance - either statically or using Reflection.
Runnable myRunnable = new MyTask();
// Add this task to run on a schedule basis dynamically.
this.dbScheduledJobs.schedule(myRunnable, cronLikeScedule);
}
}
Hope that it helps, this solution is not tested.
I need to schedule a task to run in at fixed interval of time. How can I do this with support of long intervals (for example on each 8 hours)?
I'm currently using java.util.Timer.scheduleAtFixedRate. Does java.util.Timer.scheduleAtFixedRate support long time intervals?
Use a ScheduledExecutorService:
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(yourRunnable, 8, 8, TimeUnit.HOURS);
You should take a look to Quartz it's a java framework wich works with EE and SE editions and allows to define jobs to execute an specific time
Try this way ->
Firstly create a class TimeTask that runs your task, it looks like:
public class CustomTask extends TimerTask {
public CustomTask(){
//Constructor
}
public void run() {
try {
// Your task process
} catch (Exception ex) {
System.out.println("error running thread " + ex.getMessage());
}
}
}
Then in main class you instantiate the task and run it periodically started by a precised date:
public void runTask() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 40);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Timer time = new Timer(); // Instantiate Timer Object
// Start running the task on Monday at 15:40:00, period is set to 8 hours
// if you want to run the task immediately, set the 2nd parameter to 0
time.schedule(new CustomTask(), calendar.getTime(), TimeUnit.HOURS.toMillis(8));
}
Use Google Guava AbstractScheduledService as given below:
public class ScheduledExecutor extends AbstractScheduledService {
#Override
protected void runOneIteration() throws Exception {
System.out.println("Executing....");
}
#Override
protected Scheduler scheduler() {
return Scheduler.newFixedRateSchedule(0, 3, TimeUnit.SECONDS);
}
#Override
protected void startUp() {
System.out.println("StartUp Activity....");
}
#Override
protected void shutDown() {
System.out.println("Shutdown Activity...");
}
public static void main(String[] args) throws InterruptedException {
ScheduledExecutor se = new ScheduledExecutor();
se.startAsync();
Thread.sleep(15000);
se.stopAsync();
}
}
If you have more services like this, then registering all services in ServiceManager will be good as all services can be started and stopped together. Read here for more on ServiceManager.
If you want to stick with java.util.Timer, you can use it to schedule at large time intervals. You simply pass in the period you are shooting for. Check the documentation here.
Do something every one second
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
//code
}
}, 0, 1000);
These two classes can work together to schedule a periodic task:
Scheduled Task
import java.util.TimerTask;
import java.util.Date;
// Create a class extending TimerTask
public class ScheduledTask extends TimerTask {
Date now;
public void run() {
// Write code here that you want to execute periodically.
now = new Date(); // initialize date
System.out.println("Time is :" + now); // Display current time
}
}
Run Scheduled Task
import java.util.Timer;
public class SchedulerMain {
public static void main(String args[]) throws InterruptedException {
Timer time = new Timer(); // Instantiate Timer Object
ScheduledTask st = new ScheduledTask(); // Instantiate SheduledTask class
time.schedule(st, 0, 1000); // Create task repeating every 1 sec
//for demo only.
for (int i = 0; i <= 5; i++) {
System.out.println("Execution in Main Thread...." + i);
Thread.sleep(2000);
if (i == 5) {
System.out.println("Application Terminates");
System.exit(0);
}
}
}
}
Reference https://www.mkyong.com/java/how-to-run-a-task-periodically-in-java/
If your application is already using Spring framework, you have Scheduling built in
I use Spring Framework's feature. (spring-context jar or maven dependency).
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
#Component
public class ScheduledTaskRunner {
#Autowired
#Qualifier("TempFilesCleanerExecution")
private ScheduledTask tempDataCleanerExecution;
#Scheduled(fixedDelay = TempFilesCleanerExecution.INTERVAL_TO_RUN_TMP_CLEAN_MS /* 1000 */)
public void performCleanTempData() {
tempDataCleanerExecution.execute();
}
}
ScheduledTask is my own interface with my custom method execute, which I call as my scheduled task.
You can also use JobRunr, an easy to use and open-source Java Scheduler.
To schedule a Job every 8 hours using JobRunr, you would use the following code:
BackgroundJob.scheduleRecurrently(Duration.ofHours(8), () -> yourService.methodToRunEvery8Hours());
If you are using Spring Boot, Micronaut or Quarkus, you can also use the #Recurring annotation:
public class YourService {
#Recurring(interval="PT8H")
public void methodToRunEvery8Hours() {
// your business logic
}
}
JobRunr also comes with an embedded dashboard that allows you to follow-up on how your jobs are doing.
Have you tried Spring Scheduler using annotations ?
#Scheduled(cron = "0 0 0/8 ? * * *")
public void scheduledMethodNoReturnValue(){
//body can be another method call which returns some value.
}
you can do this with xml as well.
<task:scheduled-tasks>
<task:scheduled ref = "reference" method = "methodName" cron = "<cron expression here> -or- ${<cron expression from property files>}"
<task:scheduled-tasks>
my servlet contains this as a code how to keep this in scheduler if a user presses accept
if(bt.equals("accept")) {
ScheduledExecutorService scheduler=Executors.newScheduledThreadPool(1);
String lat=request.getParameter("latlocation");
String lng=request.getParameter("lnglocation");
requestingclass.updatelocation(lat,lng);
}
There is a ScheduledFuture class in java.util.concurrent, it may helps you.
I am running a scheduled task in the web application using the java SingleThreadScheduledExecutor
The problem I have is - How do I identify whether the scheduler is still running and has not crashed?
Is there a better way of doing it rather than having another scheduler to check this particular scheduler
there is actually a way to check
public class TaskSchedulerService{
private final ThreadPoolTaskScheduler taskScheduler; //initialize it here or in constructor
private Map<String,ScheduledFuture<?>> scheduleMap = new ConcurrentHashMap<>();
public TaskSchedulerServiceImpl() {
this.schedulerName = schedulerName;
taskScheduler.initialize();
}
public boolean isScheduled(String taskId) {
final ScheduledFuture<?> exits = scheduledTasks.get(taskId);
return exits != null && exits.isDone();
}
public ScheduledFuture<?> schedule(String taskId, Runnable task, Date date) {
ScheduledFuture<?> scheduled = scheduleMap.get(taskId);
if (scheduled==null ) {
ScheduledFuture<?> future = taskScheduler.schedule(task, date);
scheduleMap.put(taskId, future);
return future;
} else {
// log it is already scheduled
return scheduled;
}
}
i know it is too late but i hope others can get benefit from it
The logic behind the implementation is whenever you are trying to schedule a task, you will have to add it to the map with the taskId as well, in this case it is better to find any task if exists in MAP or if needed remove it as well as checking if that task is done or not
The answer depends on what your scheduler does really. For instance, you can produce a file or update a field in a db or such thing that can be checked and the time interval (from now to last update) can be calculated. In your case, if the time interval of file creation or db updated is more than half an hour this means the job did stop. But notice that scheduled jobs are meant to last forever like love.
In my java web application, I want to schedule a task.
I have searched the web alot and couldn't find a suitable scheduler for my case. In the application I have different types of users. For a specific user type, I want to schedule a task.
By the time a critical action is taken by a user:
I want to send an email to that specific user and after 15 minutes
I want to send another email and after 30 minutes
I want to send another email and shut down the scheduler.
I know when the users take critical actions and how to send email but I don't have much experience about scheduling.
Can anyone help me for the case?
Why don't you use a ScheduledExecutor?
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html
It has a method schedule which allows you to schedule whatever task you want (you pass a runnable). So basically, for each user you schedule a task of sending an e-mail and scheduling another task.
import static java.util.concurrent.TimeUnit.*;
class Task implements Runnable {
private final User user;
private final int rep;
private final ScheduledExecutorService scheduler;
public Task(User user, int rep, ScheduledExecutorService scheduler) {
this.user = user;
this.rep = rep;
this.scheduler = scheduler;
}
public void run() {
// send an e-mail to user
if (rep > 0)
scheduler.schedule(new Task(user, rep - 1, scheduler), 15, MINUTES);
}
}
class Example {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void sendEmails() {
// foreach user
scheduler.submit(new Task(user, 3, scheduler));
}
}
You might want to use a scheduled thread pool with more than one thread.
Use Quartz Scheduler to schedule a task
Steps Required -
1) Quartz job
public class HelloJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Hello Quartz!");
}
}
2) Creating a trigger - CronTrigger – Run every 30 seconds
CronTrigger trigger = new CronTrigger();
trigger.setName("dummyTriggerName");
trigger.setCronExpression("0/30 * * * * ?");
3) Creating a scheduler
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
Here's a tutorial on how to use Java Timers:
http://enos.itcollege.ee/~jpoial/docs/tutorial/essential/threads/timer.html
You can create multiple Timer tasks in sequence to fufill your objective.
Example
Code Quote:
import java.util.Timer;
import java.util.TimerTask;
/**
* Simple demo that uses java.util.Timer to schedule a task
* to execute once 5 seconds have passed.
*/
public class Reminder {
Timer timer;
public Reminder(int seconds) {
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
System.out.format("Time's up!%n");
timer.cancel(); //Terminate the timer thread
}
}
public static void main(String args[]) {
new Reminder(5);
System.out.format("Task scheduled.%n");
}
}
You can also use JobRunr, an easy to use and open-source Java Scheduler.
To schedule a Job after 15 minutes using JobRunr, you would use the following code:
JobId firstEmailJobId = BackgroundJob.enqueue(() -> yourService.sendFirstEmail());
JobId secondEmailJobId = BackgroundJob.schedule(Instant.now().plus(15, minutes), () -> yourService.sendSecondEmail());
You can then repeat these steps for the other 2 emails. If you want to cancel sending these emails (e.g. when the user took action), you can easily delete these jobs again by means of the JobId (of course only if the job has not executed yet)
JobRunr also comes with automatic retries (e.g. your mailserver or sendgrid is down) and an embedded dashboard that allows you to follow-up on how your jobs are doing.
I would recommend you to take a look at the quartz scheduling API http://quartz-scheduler.org/
I have used it in several projects so far and it is really easy to setup and configure new jobs in. It supports cron based triggers or simpletriggers so you can either calculate the times for the scheduled events in your java code or you can simply pass it a cron string.
Another advantage is that its really easy to configure with spring.
I need to schedule a task to run in at fixed interval of time. How can I do this with support of long intervals (for example on each 8 hours)?
I'm currently using java.util.Timer.scheduleAtFixedRate. Does java.util.Timer.scheduleAtFixedRate support long time intervals?
Use a ScheduledExecutorService:
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(yourRunnable, 8, 8, TimeUnit.HOURS);
You should take a look to Quartz it's a java framework wich works with EE and SE editions and allows to define jobs to execute an specific time
Try this way ->
Firstly create a class TimeTask that runs your task, it looks like:
public class CustomTask extends TimerTask {
public CustomTask(){
//Constructor
}
public void run() {
try {
// Your task process
} catch (Exception ex) {
System.out.println("error running thread " + ex.getMessage());
}
}
}
Then in main class you instantiate the task and run it periodically started by a precised date:
public void runTask() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 40);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Timer time = new Timer(); // Instantiate Timer Object
// Start running the task on Monday at 15:40:00, period is set to 8 hours
// if you want to run the task immediately, set the 2nd parameter to 0
time.schedule(new CustomTask(), calendar.getTime(), TimeUnit.HOURS.toMillis(8));
}
Use Google Guava AbstractScheduledService as given below:
public class ScheduledExecutor extends AbstractScheduledService {
#Override
protected void runOneIteration() throws Exception {
System.out.println("Executing....");
}
#Override
protected Scheduler scheduler() {
return Scheduler.newFixedRateSchedule(0, 3, TimeUnit.SECONDS);
}
#Override
protected void startUp() {
System.out.println("StartUp Activity....");
}
#Override
protected void shutDown() {
System.out.println("Shutdown Activity...");
}
public static void main(String[] args) throws InterruptedException {
ScheduledExecutor se = new ScheduledExecutor();
se.startAsync();
Thread.sleep(15000);
se.stopAsync();
}
}
If you have more services like this, then registering all services in ServiceManager will be good as all services can be started and stopped together. Read here for more on ServiceManager.
If you want to stick with java.util.Timer, you can use it to schedule at large time intervals. You simply pass in the period you are shooting for. Check the documentation here.
Do something every one second
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
//code
}
}, 0, 1000);
These two classes can work together to schedule a periodic task:
Scheduled Task
import java.util.TimerTask;
import java.util.Date;
// Create a class extending TimerTask
public class ScheduledTask extends TimerTask {
Date now;
public void run() {
// Write code here that you want to execute periodically.
now = new Date(); // initialize date
System.out.println("Time is :" + now); // Display current time
}
}
Run Scheduled Task
import java.util.Timer;
public class SchedulerMain {
public static void main(String args[]) throws InterruptedException {
Timer time = new Timer(); // Instantiate Timer Object
ScheduledTask st = new ScheduledTask(); // Instantiate SheduledTask class
time.schedule(st, 0, 1000); // Create task repeating every 1 sec
//for demo only.
for (int i = 0; i <= 5; i++) {
System.out.println("Execution in Main Thread...." + i);
Thread.sleep(2000);
if (i == 5) {
System.out.println("Application Terminates");
System.exit(0);
}
}
}
}
Reference https://www.mkyong.com/java/how-to-run-a-task-periodically-in-java/
If your application is already using Spring framework, you have Scheduling built in
I use Spring Framework's feature. (spring-context jar or maven dependency).
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
#Component
public class ScheduledTaskRunner {
#Autowired
#Qualifier("TempFilesCleanerExecution")
private ScheduledTask tempDataCleanerExecution;
#Scheduled(fixedDelay = TempFilesCleanerExecution.INTERVAL_TO_RUN_TMP_CLEAN_MS /* 1000 */)
public void performCleanTempData() {
tempDataCleanerExecution.execute();
}
}
ScheduledTask is my own interface with my custom method execute, which I call as my scheduled task.
You can also use JobRunr, an easy to use and open-source Java Scheduler.
To schedule a Job every 8 hours using JobRunr, you would use the following code:
BackgroundJob.scheduleRecurrently(Duration.ofHours(8), () -> yourService.methodToRunEvery8Hours());
If you are using Spring Boot, Micronaut or Quarkus, you can also use the #Recurring annotation:
public class YourService {
#Recurring(interval="PT8H")
public void methodToRunEvery8Hours() {
// your business logic
}
}
JobRunr also comes with an embedded dashboard that allows you to follow-up on how your jobs are doing.
Have you tried Spring Scheduler using annotations ?
#Scheduled(cron = "0 0 0/8 ? * * *")
public void scheduledMethodNoReturnValue(){
//body can be another method call which returns some value.
}
you can do this with xml as well.
<task:scheduled-tasks>
<task:scheduled ref = "reference" method = "methodName" cron = "<cron expression here> -or- ${<cron expression from property files>}"
<task:scheduled-tasks>
my servlet contains this as a code how to keep this in scheduler if a user presses accept
if(bt.equals("accept")) {
ScheduledExecutorService scheduler=Executors.newScheduledThreadPool(1);
String lat=request.getParameter("latlocation");
String lng=request.getParameter("lnglocation");
requestingclass.updatelocation(lat,lng);
}
There is a ScheduledFuture class in java.util.concurrent, it may helps you.