Schedule Java EE 7 Batch Jobs
Java EE 7 added the capability to perform Batch jobs in a standard way using JSR 352.
1 2 3 4 5 6 7 | < step id = "myStep" > < chunk item-count = "3" > < reader ref = "myItemReader" /> < processor ref = "myItemProcessor" /> < writer ref = "myItemWriter" /> </ chunk > |
This code fragment is the Job Specification Language defined as XML, a.k.a. Job XML. It defines a canonical job, with a single step, using item-oriented or chunk-oriented processing. A chunk can have a reader, optional processor, and a writer. Each of these elements are identified using the corresponding elements in the Job XML, and are CDI beans packaged in the archive.
This job can be easily started using:
1 | BatchRuntime.getJobOperator().start( "myJob" , new Properties()); |
A typical question asked in different forums and conferences is how to schedule these jobs in a Java EE runtime. Batch 1.0 API itself does not offer anything to be schedule these jobs. However Java EE platform offers three different ways to schedule these jobs:
- Use the
@javax.ejb.Schedule
annotation in an EJB. Here is a sample code that will trigger the execution of batch job at 11:59:59 PM every day.1234567@Singleton
public
class
MyEJB {
@Schedule
(hour =
"23"
, minute =
"59"
, second =
"59"
)
public
void
myJob() {
BatchRuntime.getJobOperator().start(
"myJob"
,
new
Properties());
}
}
Of course, you can change the parameters of
@Schedule
to start the batch job at the desired time. - Use
ManagedScheduledExecutorService
usingjavax.enterprise.concurrent.Trigger
as shown:0102030405060708091011121314151617181920212223242526@Stateless
public
class
MyStatelessEJB {
@Resource
ManagedScheduledExecutorService executor;
public
void
runJob() {
executor.schedule(
new
MyJob(),
new
Trigger() {
public
Date getNextRunTime(LastExecution lastExecutionInfo, Date taskScheduledTime) {
Calendar cal = Calendar.getInstance();
cal.setTime(taskScheduledTime);
cal.add(Calendar.DATE,
1
);
return
cal.getTime();
}
public
boolean
skipRun(LastExecution lastExecutionInfo, Date scheduledRunTime) {
return
null
== lastExecutionInfo;
}
});
}
public
void
cancelJob() {
executor.shutdown();
}
}
Call
runJob
to initiate job execution andcancelJob
to terminate job execution. In this case, a new job is started a day later than the previous task. And its not started until previous one is terminated. You will need more error checks for proper execution.MyJob is very trivial:
1234567public
class
MyJob
implements
Runnable {
public
void
run() {
BatchRuntime.getJobOperator().start(
"myJob"
,
new
Properties());
}
}
Of course, you can automatically schedule it by calling this code in
@PostConstruct
. - A slight variation of second technique allows to run the job after a fixed delay as shown:123
public
void
runJob2() {
executor.scheduleWithFixedDelay(
new
MyJob(),
2
,
3
, TimeUnit.HOURS);
}
The first task is executed 2 hours after the
runJob2
method is called. And then with a 3 hours delay between subsequent execution.
This support is available to you within the Java EE platform. In addition, you can also invoke BatchRuntime.getJobOperator().start("myJob", new Properties());
from any of your Quartz-scheduled methods as well.
- You can try all of this on WildFly.
- And there are a ton of Java EE 7 samples at github.com/javaee-samples/javaee7-samples.
- This particular sample is available at github.com/javaee-samples/javaee7-samples/tree/master/batch/scheduling.
How are you scheduling your Batch jobs ?
Reference: | Schedule Java EE 7 Batch Jobs from our JCG partner Arun Gupta at the Miles to go 2.0 … blog. |