はじめに
本記事はLiferayへのサーバーサイドのカスタマイズを含みますのでLiferay PaaSおよびLiferay Self-Hosted利用者向けの記事になります。
LiferayではこれまでMessageBusの仕組みを使い、自身でMessageListenerを実装してQuartzスケジューラーを介してCRONやインターバル形式でのスケジューラタスクを実装することができました。
しかし、クラスタ環境下での制御など開発者側で考慮しなければならない点が多く、実行履歴の保存なども自身で行わねばならず、管理面での課題がありました。
そこでLiferay DXP 7.3からJob Scheduler Frameworkが追加されました。
本記事ではこのJob Scheduler Frameworkを使ってLiferay上でスケジューラを実装・設定する手順を紹介します。
Job Scheduler Frameworkの仕組み
Job Scheduler Frameworkでは開発者が実装する必要があるのはDispatchTaskExecutorインターフェースを実装したコンポーネントのみです。
このコンポーネントで実行するタスクを実装するだけでよいです。
スケジューリングや実行結果ログなどはJob Scheduler Framework側で管理してくれます。

タスク作成
コード全体
サンプルとしてログに現在のポータルのユーザー数を出力するタスクを実装します。
@Component(
service = DispatchTaskExecutor.class,
property = {
"dispatch.task.executor.name=sample-dispatch-task",
"dispatch.task.executor.type=sample-dispatch-task"
}
)
public class SampleDispatchExecutor extends BaseDispatchTaskExecutor {
@Override
public String getName() {
return "Sample Dispatch Executor";
}
@Override
public void doExecute(
DispatchTrigger dispatchTrigger,
DispatchTaskExecutorOutput dispatchTaskExecutorOutput) throws Exception {
long companyId = dispatchTrigger.getCompanyId();
int usersCount = _userLocalService.getCompanyUsersCount(companyId);
_log.info(LOG_MESSAGE_FORMAT.formatted(companyId, usersCount));
}
@Reference
private UserLocalService _userLocalService;
private static final String LOG_MESSAGE_FORMAT = "Current Portal User Count: {companyId=%d, usersCount=%d}";
private static final Log _log = LogFactoryUtil.getLog(SampleDispatchExecutor.class);
}
Component
まずComponent部分ですが、DispatchTaskExecutorの実装になるのでこれをserviceに指定します。
property に以下の二つを指定しますが基本的には同じ値でよいです。
- dispatch.task.executor.name:当該タスクの表示名(Language.properties対応)
- dispatch.task.executor.type:当該タスクの識別子
これらはこのタスクの識別子およびラベルです。
ラベルに関しては後述のgetNameメソッドがありますが、将来的にこのdispatch.task.executor.nameに移行する方針です(たぶん)。
ここではサンプル用なので「sample-dispatch-task」という名前で定義しています。
@Component(
service = DispatchTaskExecutor.class,
property = {
"dispatch.task.executor.name=sample-dispatch-task",
"dispatch.task.executor.type=sample-dispatch-task"
}
)
getName()
このgetNameメソッドは7.4で非推奨になっています。
とはいえ、Liferayのソースコード上はリスト表示等でこのメソッドを使ってタスク名を出力しています。
将来的に上述のdispatch.task.executor.nameに置き換わるんだろうなー。と思っています。
@Override
public String getName() {
return "Sample Dispatch Executor";
}
doExecute()
このメソッドの中にタスクで実行する処理を実装します。
要はこのタスクのビジネスロジックです。
今回はサンプルなのでタスクを実行したポータルインスタンス内のユーザー数をロギングしています。
この中でAPI等を使って外部システムと連携したり、Liferay内のデータを集計してレポートを作ったり。とお好みのタスクを実装できます。
public void doExecute(
DispatchTrigger dispatchTrigger,
DispatchTaskExecutorOutput dispatchTaskExecutorOutput) throws Exception {
long companyId = dispatchTrigger.getCompanyId();
int usersCount = _userLocalService.getCompanyUsersCount(companyId);
_log.info(LOG_MESSAGE_FORMAT.formatted(companyId, usersCount));
}
動作確認
Dispatch画面での設定は以下の流れになります。
ディスパッチ管理画面に移動
コントロールパネルのディスパッチメニューをクリック

タスクの新規作成
「新規作成」ボタンをクリックしてスケジューリングしたいタスクを選択
今回は作成した「Sample Dispatch Executor」を選択

タスクの表示名とプロパティ設定の編集が可能、ここではそのまま「保存」をクリック

作成すると「送信トリガー」タブの一覧に表示され、「今すぐ実行」ボタンで即時実行も可能

実行すると以下のようなロギングがされ、期待通りタスクが実行されたことを確認できる

タスクのスケジューリング
三点リーダーの「編集」からタスクの実行ログ確認や、スケジューリング可能

「ログ」タブはタスクの実行ログ画面で、以下の情報を確認可能
- いつタスク実行が開始したのか
- タスク実行開始の予定日時
- 実行にどれくらいの時間がかかったのか
- 実行結果のステータス

「ディスパッチトリガー」タブではタスクのスケジュール設定を行うことが可能
Cron式で実行のタイミングをcron expressionで定義

まとめ
いかがでしたでしょうか。
このようにLiferayのJob Scheduler Frameworkを使うと、開発者は実現したいビジネスロジックの実装に集中できます。
さらにロギングやスケジューリングの部分はLiferayの標準機能で管理されるので、バージョンアップの際にも考慮しなくてもよくなります。
OxygenDesignではSelf HostedやPaaSのお客様向けにタスク実装や旧来のMessageBus形式からの移行のコンサルテーションの経験も豊富です。
お困りでしたらぜひお問い合わせください!
まつもとでした!






