Wiki source code of Use java in scheduler jobs
Version 2.1 by Mohamed Boussaa on 2016/06/21
Show last authors
author | version | line-number | content |
---|---|---|---|
1 | XWiki provides a Scheduler Application that offers the possiblity of creating jobs and perform actions on these jobs (Schedule, Trigger, Cancel ...). | ||
2 | Jobs created by the scheduler application executes a groovy script periodicaly following a predifined period that is using a Cron expression. | ||
3 | |||
4 | A Scheduler Job is an **XWiki.SchedulerJobClass** object attached to a wiki page. | ||
5 | |||
6 | The script to excute is set in the Job Script property of the **XWiki.SchedulerJobClass** object, it is a groovy script. | ||
7 | |||
8 | Find more information about the scheduler Application [[here>>http://extensions.xwiki.org/xwiki/bin/view/Extension/Scheduler+Application]]. | ||
9 | |||
10 | In this post we will provide a solution to use JAVA code instead of Groovy in the Job Script. | ||
11 | |||
12 | ==Use Java in the job script== | ||
13 | To use java in the Job script you will need 2 steps: | ||
14 | 1) Create a java class that extends **com.xpn.xwiki.plugin.scheduler.AbstractJob** class and implements the **org.quartz.Job** interface. | ||
15 | 2) Set the Job **class** property with the full java class name and let the Job script property empty. | ||
16 | |||
17 | === Create the java class=== | ||
18 | The class will need a Cron experession to be used to excute the job periodically. The Cron expression will be provided by the Scheduler Job object. | ||
19 | |||
20 | In the java class we will need to override the **executeJob** method that will be called periodically from the scheduler. | ||
21 | |||
22 | We will take the **watchlist scheduler jobs**. as an example, the Scheduler job page is **Scheduler.WatchListDailyNotifier** in your Wiki and the java class is [[here>>https://github.com/xwiki/xwiki-platform/blob/master/xwiki-platform-core/xwiki-platform-watchlist/xwiki-platform-watchlist-api/src/main/java/org/xwiki/watchlist/internal/job/WatchListJob.java]] | ||
23 | |||
24 | ====Methods that need to be defined in the class==== | ||
25 | |||
26 | **init** method: Sets objects required by the Job : XWiki, XWikiContext, Components ... etc. | ||
27 | |||
28 | {{code}} | ||
29 | ... | ||
30 | public void init(JobExecutionContext jobContext) throws Exception | ||
31 | { | ||
32 | JobDataMap data = jobContext.getJobDetail().getJobDataMap(); | ||
33 | |||
34 | this.watchlist = Utils.getComponent(WatchList.class); | ||
35 | this.schedulerJobObject = (BaseObject) data.get("xjob"); | ||
36 | this.watchListJobObject = | ||
37 | getXWikiContext().getWiki().getDocument(this.schedulerJobObject.getDocumentReference(), getXWikiContext()) | ||
38 | .getXObject(WatchListJobClassDocumentInitializer.DOCUMENT_REFERENCE); | ||
39 | } | ||
40 | ... | ||
41 | {{/code}} | ||
42 | |||
43 | **executeJob** method: Method called from the scheduler. | ||
44 | |||
45 | {{code}} | ||
46 | ... | ||
47 | @Override | ||
48 | public void executeJob(JobExecutionContext jobContext) throws JobExecutionException | ||
49 | { | ||
50 | try { | ||
51 | init(jobContext); | ||
52 | |||
53 | if (this.watchListJobObject == null) { | ||
54 | return; | ||
55 | } | ||
56 | |||
57 | Collection<String> subscribers = getSubscribers(); | ||
58 | |||
59 | // Stop here if nobody is interested. | ||
60 | if (!hasSubscribers()) { | ||
61 | return; | ||
62 | } | ||
63 | |||
64 | // Determine what happened since the last execution for everybody. | ||
65 | Date previousFireTime = getPreviousFireTime(); | ||
66 | WatchListEventMatcher eventMatcher = Utils.getComponent(WatchListEventMatcher.class); | ||
67 | List<WatchListEvent> events = eventMatcher.getEventsSince(previousFireTime); | ||
68 | setPreviousFireTime(); | ||
69 | |||
70 | // Stop here if nothing happened in the meantime. | ||
71 | if (events.size() == 0) { | ||
72 | return; | ||
73 | } | ||
74 | |||
75 | // Notify all the interested subscribers of the events that occurred. | ||
76 | // When processing the events, a subscriber will only be notified of events that interest him. | ||
77 | Map<String, Object> notificationData = new HashMap<>(); | ||
78 | notificationData.put(DefaultWatchListNotifier.PREVIOUS_FIRE_TIME_VARIABLE, previousFireTime); | ||
79 | |||
80 | String mailTemplate = | ||
81 | this.watchListJobObject.getStringValue(WatchListJobClassDocumentInitializer.TEMPLATE_FIELD); | ||
82 | notificationData.put(WatchListEventMimeMessageFactory.TEMPLATE_PARAMETER, mailTemplate); | ||
83 | |||
84 | // Send the notification for processing. | ||
85 | this.watchlist.getNotifier().sendNotification(subscribers, events, notificationData); | ||
86 | } catch (Exception e) { | ||
87 | // We're in a job, we don't throw exceptions | ||
88 | LOGGER.error("Exception while running job", e); | ||
89 | } | ||
90 | } | ||
91 | ... | ||
92 | {{/code}} | ||
93 | |||
94 | Find a complte example here: https://github.com/xwiki/xwiki-platform/blob/master/xwiki-platform-core/xwiki-platform-watchlist/xwiki-platform-watchlist-api/src/main/java/org/xwiki/watchlist/internal/job/WatchListJob.java | ||
95 | |||
96 | ===Set the Job class property with the java full class name=== | ||
97 | Edit the **Scheduler.WatchListDailyNotifier** in Object mode and update the **Job class** property of the **XWiki.SchedulerJobClass** object with the full java class name and let the **Job script** property empty. | ||
98 | |||
99 | {{image reference="edit-job.png"/}} | ||
100 | //Scheduler job object// | ||
101 | |||
102 | == Conclusion == | ||
103 | |||
104 | This approach will allow you to take advantage of all power that Java provides in scheduler jobs. |