0
# Task Scheduling
1
2
Comprehensive task scheduling capabilities supporting both declarative annotation-driven scheduling and programmatic task management. Includes CRON expression support, fixed-rate/fixed-delay scheduling, and custom executor configuration.
3
4
## Capabilities
5
6
### @Scheduled Annotation
7
8
Declarative scheduling annotation for automatic task execution with various timing strategies.
9
10
```java { .api }
11
/**
12
* Annotation for scheduling recurring tasks
13
* Can be repeated on a single method for multiple schedules
14
*/
15
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
16
@Retention(RetentionPolicy.RUNTIME)
17
@Repeatable(Schedules.class)
18
public @interface Scheduled {
19
20
/**
21
* CRON expression for complex scheduling patterns
22
* @return CRON expression string (e.g., "0 0 2 * * ?" for daily at 2 AM)
23
*/
24
String cron() default "";
25
26
/**
27
* Time zone ID for CRON expression evaluation
28
* @return Zone ID string (e.g., "America/New_York")
29
*/
30
String zoneId() default "";
31
32
/**
33
* Fixed delay between completion of one execution and start of next
34
* @return Duration string (e.g., "30s", "5m", "1h")
35
*/
36
String fixedDelay() default "";
37
38
/**
39
* Initial delay before first execution
40
* @return Duration string (e.g., "10s", "1m")
41
*/
42
String initialDelay() default "";
43
44
/**
45
* Fixed rate between execution starts (regardless of completion time)
46
* @return Duration string (e.g., "1m", "15m")
47
*/
48
String fixedRate() default "";
49
50
/**
51
* Named scheduler bean to use for execution
52
* @return Scheduler name (default: TaskExecutors.SCHEDULED)
53
*/
54
String scheduler() default TaskExecutors.SCHEDULED;
55
56
/**
57
* Conditional expression for execution control
58
* @return SpEL expression that must evaluate to true for execution
59
*/
60
String condition() default "";
61
}
62
63
/**
64
* Container annotation for multiple @Scheduled annotations
65
*/
66
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
67
@Retention(RetentionPolicy.RUNTIME)
68
public @interface Schedules {
69
Scheduled[] value();
70
}
71
```
72
73
**Usage Examples:**
74
75
```java
76
import io.micronaut.scheduling.annotation.Scheduled;
77
import jakarta.inject.Singleton;
78
79
@Singleton
80
public class ScheduledTasks {
81
82
// Fixed delay scheduling
83
@Scheduled(fixedDelay = "30s", initialDelay = "10s")
84
public void maintenanceTask() {
85
System.out.println("Running maintenance every 30 seconds after completion");
86
}
87
88
// Fixed rate scheduling
89
@Scheduled(fixedRate = "1m")
90
public void healthCheck() {
91
System.out.println("Health check every minute");
92
}
93
94
// CRON-based scheduling
95
@Scheduled(cron = "0 0 2 * * ?") // Daily at 2 AM
96
public void dailyBackup() {
97
System.out.println("Running daily backup");
98
}
99
100
// CRON with timezone
101
@Scheduled(cron = "0 30 9 * * MON-FRI", zoneId = "America/New_York")
102
public void businessHoursTask() {
103
System.out.println("Business hours task in NY timezone");
104
}
105
106
// Multiple schedules on same method
107
@Scheduled(cron = "0 0 6 * * ?") // 6 AM daily
108
@Scheduled(cron = "0 0 18 * * ?") // 6 PM daily
109
public void twiceDaily() {
110
System.out.println("Running twice daily");
111
}
112
113
// Conditional execution
114
@Scheduled(fixedRate = "5m", condition = "${app.monitoring.enabled:true}")
115
public void conditionalMonitoring() {
116
System.out.println("Conditional monitoring task");
117
}
118
119
// Custom executor
120
@Scheduled(fixedDelay = "1s", scheduler = TaskExecutors.IO)
121
public void ioTask() {
122
System.out.println("I/O task on dedicated executor");
123
}
124
}
125
```
126
127
### @Async and @ExecuteOn Annotations
128
129
Control asynchronous execution and executor selection for scheduled and regular methods.
130
131
```java { .api }
132
/**
133
* Execute method asynchronously on specified thread pool
134
* Returns CompletableFuture for async result handling
135
*/
136
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
137
@Retention(RetentionPolicy.RUNTIME)
138
public @interface Async {
139
/**
140
* Executor service name for async execution
141
* @return Executor name (default: TaskExecutors.SCHEDULED)
142
*/
143
String value() default TaskExecutors.SCHEDULED;
144
}
145
146
/**
147
* Specify which executor service to run operation on
148
* More explicit than @Async for executor selection
149
*/
150
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
151
@Retention(RetentionPolicy.RUNTIME)
152
public @interface ExecuteOn {
153
/**
154
* Name of configured executor service
155
* @return Executor service name
156
*/
157
String value();
158
}
159
```
160
161
**Usage Examples:**
162
163
```java
164
import io.micronaut.scheduling.annotation.Async;
165
import io.micronaut.scheduling.annotation.ExecuteOn;
166
import java.util.concurrent.CompletableFuture;
167
168
@Singleton
169
public class AsyncService {
170
171
@Async
172
public CompletableFuture<String> processDataAsync(String data) {
173
// Long-running operation
174
return CompletableFuture.completedFuture("Processed: " + data);
175
}
176
177
@ExecuteOn(TaskExecutors.IO)
178
public void fileOperation() {
179
// I/O intensive operation on I/O thread pool
180
}
181
182
@ExecuteOn(TaskExecutors.BLOCKING)
183
public String blockingOperation() {
184
// Blocking operation on dedicated blocking thread pool
185
return "Result";
186
}
187
188
@Scheduled(fixedRate = "30s")
189
@ExecuteOn(TaskExecutors.IO)
190
public void scheduledIoTask() {
191
// Scheduled task that runs on I/O executor
192
}
193
}
194
```
195
196
### TaskScheduler Interface
197
198
Programmatic task scheduling interface for dynamic scheduling needs.
199
200
```java { .api }
201
/**
202
* Interface for programmatic task scheduling
203
* Provides methods for various scheduling patterns
204
*/
205
public interface TaskScheduler {
206
207
/**
208
* Schedule task using CRON expression
209
* @param cron CRON expression string
210
* @param command Runnable task to execute
211
* @return ScheduledFuture for task control
212
*/
213
ScheduledFuture<?> schedule(String cron, Runnable command);
214
215
/**
216
* Schedule callable task using CRON expression
217
* @param cron CRON expression string
218
* @param command Callable task to execute
219
* @return ScheduledFuture with result type
220
*/
221
<V> ScheduledFuture<V> schedule(String cron, Callable<V> command);
222
223
/**
224
* Schedule task using CRON expression with specific timezone
225
* @param cron CRON expression string
226
* @param timezoneId Timezone ID for CRON evaluation (null for system timezone)
227
* @param command Runnable task to execute
228
* @return ScheduledFuture for task control
229
*/
230
ScheduledFuture<?> schedule(@NonNull String cron, @Nullable String timezoneId, @NonNull Runnable command);
231
232
/**
233
* Schedule callable task using CRON expression with specific timezone
234
* @param cron CRON expression string
235
* @param timezoneId Timezone ID for CRON evaluation (null for system timezone)
236
* @param command Callable task to execute
237
* @return ScheduledFuture with result type
238
*/
239
<V> ScheduledFuture<V> schedule(@NonNull String cron, @Nullable String timezoneId, @NonNull Callable<V> command);
240
241
/**
242
* Schedule task with initial delay
243
* @param delay Duration to wait before execution
244
* @param command Runnable task to execute
245
* @return ScheduledFuture for task control
246
*/
247
ScheduledFuture<?> schedule(Duration delay, Runnable command);
248
249
/**
250
* Schedule callable task with initial delay
251
* @param delay Duration to wait before execution
252
* @param callable Callable task to execute
253
* @return ScheduledFuture with result type
254
*/
255
<V> ScheduledFuture<V> schedule(Duration delay, Callable<V> callable);
256
257
/**
258
* Schedule task at fixed rate (time between execution starts)
259
* @param initialDelay Initial delay before first execution
260
* @param period Time between execution starts
261
* @param command Runnable task to execute
262
* @return ScheduledFuture for task control
263
*/
264
ScheduledFuture<?> scheduleAtFixedRate(@Nullable Duration initialDelay, Duration period, Runnable command);
265
266
/**
267
* Schedule task with fixed delay (time between execution end and next start)
268
* @param initialDelay Initial delay before first execution (nullable)
269
* @param delay Time between execution end and next start
270
* @param command Runnable task to execute
271
* @return ScheduledFuture for task control
272
*/
273
ScheduledFuture<?> scheduleWithFixedDelay(@Nullable Duration initialDelay, Duration delay, Runnable command);
274
}
275
```
276
277
**Usage Examples:**
278
279
```java
280
import io.micronaut.scheduling.TaskScheduler;
281
import java.time.Duration;
282
import java.util.concurrent.ScheduledFuture;
283
284
@Singleton
285
public class DynamicScheduler {
286
287
private final TaskScheduler taskScheduler;
288
289
public DynamicScheduler(TaskScheduler taskScheduler) {
290
this.taskScheduler = taskScheduler;
291
}
292
293
public ScheduledFuture<?> scheduleMaintenanceWindow(String cronExpression) {
294
return taskScheduler.schedule(cronExpression, () -> {
295
System.out.println("Maintenance window started");
296
performMaintenance();
297
});
298
}
299
300
public ScheduledFuture<String> scheduleReport(Duration delay) {
301
return taskScheduler.schedule(delay, () -> {
302
return generateReport();
303
});
304
}
305
306
public ScheduledFuture<?> startPeriodicBackup() {
307
return taskScheduler.scheduleAtFixedRate(
308
Duration.ofMinutes(5), // Initial delay
309
Duration.ofHours(1), // Every hour
310
this::performBackup
311
);
312
}
313
}
314
```
315
316
### Task Executors
317
318
Constants interface defining standard executor names for task execution.
319
320
```java { .api }
321
/**
322
* Standard executor service names used throughout Micronaut
323
* Use these constants to reference configured executors
324
*/
325
public interface TaskExecutors {
326
/** I/O task executor for non-blocking I/O operations */
327
String IO = "io";
328
329
/** Blocking task executor for operations that may block threads */
330
String BLOCKING = "blocking";
331
332
/** Virtual threads executor (requires Java 19+ with preview or Java 21+) */
333
String VIRTUAL = "virtual";
334
335
/** Scheduled task executor for @Scheduled methods */
336
String SCHEDULED = "scheduled";
337
338
/** Message consumer executor for message processing */
339
String MESSAGE_CONSUMER = "consumer";
340
}
341
```
342
343
### CronExpression Class
344
345
Utility class for parsing and evaluating CRON expressions.
346
347
```java { .api }
348
/**
349
* CRON expression parser and evaluator
350
* Supports standard CRON format with seconds field
351
*/
352
public class CronExpression {
353
354
/**
355
* Create CronExpression from string
356
* @param cronExpression CRON expression string (6 or 7 fields)
357
* @return CronExpression instance
358
* @throws IllegalArgumentException if expression is invalid
359
*/
360
public static CronExpression create(String cronExpression);
361
362
/**
363
* Calculate next execution time after the given time
364
* @param afterTime Reference time to find next execution after
365
* @return Next execution time within next 4 years
366
*/
367
public ZonedDateTime nextTimeAfter(ZonedDateTime afterTime);
368
369
/**
370
* Calculate next execution time after given time with duration limit
371
* @param afterTime Reference time to find next execution after
372
* @param durationInMillis Maximum duration in milliseconds to search
373
* @return Next execution time within given duration
374
*/
375
public ZonedDateTime nextTimeAfter(ZonedDateTime afterTime, long durationInMillis);
376
377
/**
378
* Calculate next execution time after given time with barrier limit
379
* @param afterTime Reference time to find next execution after
380
* @param dateTimeBarrier Upper limit for search
381
* @return Next execution time within given barrier
382
*/
383
public ZonedDateTime nextTimeAfter(ZonedDateTime afterTime, ZonedDateTime dateTimeBarrier);
384
385
/**
386
* Get the underlying cron expression string
387
* @return The cron expression as string
388
*/
389
public String getExpression();
390
}
391
```
392
393
**Usage Examples:**
394
395
```java
396
import io.micronaut.scheduling.cron.CronExpression;
397
import java.time.ZonedDateTime;
398
399
public class CronExpressionExample {
400
401
public void demonstrateCronExpression() {
402
// Create CRON expression for every weekday at 9:30 AM
403
CronExpression cron = CronExpression.create("0 30 9 * * MON-FRI");
404
405
ZonedDateTime now = ZonedDateTime.now();
406
ZonedDateTime nextRun = cron.nextTimeAfter(now);
407
408
System.out.println("Next execution: " + nextRun);
409
System.out.println("Cron expression: " + cron.getExpression());
410
}
411
}
412
```
413
414
### Task Exception Handling
415
416
Interface for handling exceptions that occur during scheduled task execution.
417
418
```java { .api }
419
/**
420
* Handler for exceptions that occur during scheduled task execution
421
* Implement this interface to customize error handling behavior
422
*/
423
public interface TaskExceptionHandler {
424
425
/**
426
* Handle exception from scheduled task
427
* @param task The scheduled task that threw the exception
428
* @param throwable The exception that was thrown
429
*/
430
void handle(ScheduledFuture<?> task, Throwable throwable);
431
}
432
```
433
434
**Usage Example:**
435
436
```java
437
import io.micronaut.scheduling.TaskExceptionHandler;
438
import jakarta.inject.Singleton;
439
440
@Singleton
441
public class CustomTaskExceptionHandler implements TaskExceptionHandler {
442
443
@Override
444
public void handle(ScheduledFuture<?> task, Throwable throwable) {
445
logger.error("Scheduled task failed", throwable);
446
447
// Custom logic: retry, alert, etc.
448
if (throwable instanceof SQLException) {
449
// Handle database errors specially
450
notifyDatabaseAdmin(throwable);
451
}
452
}
453
}
454
```
455
456
## Exception Types
457
458
### SchedulerConfigurationException
459
460
Exception thrown for scheduler configuration problems.
461
462
```java { .api }
463
/**
464
* Exception for scheduler configuration problems
465
* Extends configuration exception hierarchy
466
*/
467
public class SchedulerConfigurationException extends ConfigurationException {
468
public SchedulerConfigurationException(String message);
469
public SchedulerConfigurationException(String message, Throwable cause);
470
}
471
```
472
473
### TaskExecutionException
474
475
Exception thrown during task execution failures.
476
477
```java { .api }
478
/**
479
* Runtime exception for task execution failures
480
* Wraps underlying exceptions from scheduled tasks
481
*/
482
public class TaskExecutionException extends RuntimeException {
483
public TaskExecutionException(String message);
484
public TaskExecutionException(String message, Throwable cause);
485
}
486
```