here が重複していることは知っていますが、これはおそらくまさに私の場合です。
Springアプリケーションコンテキストを使用して、Java Webアプリケーションを操作します。このコンテキストでは、Quartzを使用してスケジュールされたジョブを定義しました。これらのジョブは、.propertiesファイルで定義されたcronによってトリガーされます。
Springコンテキストはwar内に埋め込まれていますが、.propertiesファイルはアプリケーションサーバー(この特定の場合はTomcat)上にあります。
これは問題なく、環境(開発、統合、生産など)に応じて異なるcronを定義できます。
現在、このアプリケーションを自分のコンピューターでローカルに実行するとき、これらのジョブが実行されることは望みません。トリガーしないcron式を記述する方法はありますか?
Quartz 1では、次のcronを使用できます:59 59 23 31 12 ? 2099
(最後の有効な日付)。
Quartz 2では、次のcronを使用できます:0 0 0 1 1 ? 2200
org.quartz.CronExpression
を使用して簡単なテストを行いました。
String exp = "0 0 0 1 1 ? 3000";
boolean valid = CronExpression.isValidExpression(exp);
System.out.println(valid);
if (valid) {
CronExpression cronExpression = new CronExpression(exp);
System.out.println(cronExpression.getNextValidTimeAfter(new Date()));
}
String exp = "# 0 0 0 1 1 ?";
を実行すると、isValid
テストはfalse
を返します。
上記のサンプルでは、出力は次のとおりです。
true
null
意味:
ただし、スケジューラーがcronトリガーを受け入れるには、後者mustが将来の日付に一致する必要があります。
私は数年試してみましたが、年が2300を超えると、Quartzはもう気にしないようです(ただし、その年の最大値についての言及は見つかりませんでした Quartz 2のドキュメント )。これを行うためのよりクリーンな方法があるかもしれませんが、これは今のところ私のニーズを満たすでしょう。
だから、最終的に、私が提案するcronは0 0 0 1 1 ? 2200
です。
Quartz 1では、 2099は最後の有効な年 であることに注意してください。したがって、 Maciej Matysの提案 :59 59 23 31 12 ? 2099
を使用するようにcron式を調整できます。
Arnaud Denoyelle よりエレガントなものを提案しました。上記の私のテストは正しい表現として検証します。遠い未来の日付を選択する代わりに、遠い過去の日付を選択してください:
0 0 0 1 1 ? 1970
(Quartzドキュメントによる最初の有効な式)。
この解決策は機能しません。
hippofluff は、Quartzが過去に式を検出すると再び実行されることはないため、例外をスローすることを強調しています。
org.quartz.SchedulerException: Based on configured schedule, the given trigger will never fire.
これはQuartzにあったようです 長い間 。
これは私のテストの弱点を浮き彫りにします:CronExpression
をテストする場合は、を覚えておく必要がありますnextValidTime
1。それ以外の場合、それを渡すスケジューラは、上記の例外で単に拒否します。
次のようにテストコードを調整することをお勧めします。
String exp = "0 0 0 1 1 ? 3000";
boolean valid = CronExpression.isValidExpression(exp);
if (valid) {
CronExpression cronExpression = new CronExpression(exp);
valid = cronExpression.getNextValidTimeAfter(new Date()) != null;
}
System.out.println("Can I use <" + exp + ">? " + (valid ? "Go ahead!" : "This shall fail."));
考えてみる必要はありません。出力を読むだけです。
1 これは、Arnaudのソリューションをテストして私を馬鹿にし、テストが私の証拠ではなかったことを証明するときに忘れていた部分です。
技術的には、オプションのQuartz年フィールドの有効な値は1970〜2099であるため、2300は期待値ではありません。私はあなたが本当にこれを行う必要があり、Quartzのバージョンが有効なcron構文を強制しようとすると仮定しています等々)。
現在、Resque-scheduler for Railsで次のコードを使用しています。これは、検証済みのcrontab形式のスケジュール情報を受け入れ、手動実行のみのテストジョブを作成します。
cron: "0 5 31 2 *"
ジョブは、実行する前に早朝 2月31日 を辛抱強く待ちます。 Quartz crontrigger の同等のものについては、次の行またはその変形を試してください。
0 0 5 31 2 ?
これを試してください:59 59 23 31 12 ? 2099
同様の問題-cron式を無効にする-を解決しようとしたときにこれを見つけましたが、有効な将来のスケジュール日付を要求するという同じ問題に遭遇しました。
また、7つの値の構文を使用して問題が発生しました-cronスケジュールで年を指定できません。
だから私はこれを使用しました:0 0 3? 2 MON#5
次に実行されるのは次のとおりです。
したがって、本質的に、すべての意図と目的に対して、無効になっています。 :)
あ。 Curses、これはQuartzスケジューラー構文でのみ機能します-Spring CronTrigger構文は、5番目の月曜日にMON#5を許可しません
したがって、次善の策は0 0 3 29 2です。 2月29日(うるう年)の午前3時にのみ実行されます。
現在、このアプリケーションを自分のコンピューターでローカルに実行するとき、これらのジョブが実行されることは望みません。トリガーしないcron式を記述する方法はありますか?
コンピューターでスケジュールを無効にする場合、いくつかの方法でそれを実現できます。
最初に、Quartzの構成を@Profile
ベースの構成に移動し、このプロファイルをローカルで有効にしないでください。プロファイルがアクティブでない場合、Quartzはまったく起動しません。
別の方法は、Quartzが自動的に起動しないように構成することです。 devプロファイルに登録されているBeanPostProcessor
に設定できるSchedulerFactoryBean#setAutoStartup()
があります。このスレッドは非常に古いものですが、Spring BootはSchedulerFactoryBeanCustomizer
Beanを登録して同じことを行う代替手段を提供します。
@Scheduled(cron="")
式で式を使用している場合(技術的にはクォーツを使用せず、むしろ春によく使用されます)、7フィールドの将来のソリューションではなく、これらのオプションを使用できます。
"${your.cron.prop:-}
を使用し、プロパティを無効に設定しないでください- @ Scheduled を参照してください@ConditionalOnProperty("my.scheduleproperty.active")
アノテーションを使用し、プロパティを設定しない(またはfalse
に設定する)ことにより、@Scheduled
メソッドを使用してBean /サービスを無効にします。