Quartz: expression de Cron qui ne sera jamais exécutée

je sais qu'il y a un double ici , ce qui est probablement exactement mon cas, bien que cela mériterait une meilleure explication, que je vais essayer de fournir ici.

je travaille avec une application Web Java en utilisant un contexte D'application printemps. Dans ce contexte, j'ai défini les tâches programmées en utilisant le Quartz. Ces emplois sont déclenchés par un cron défini au point a.fichier de propriétés.

le contexte du printemps est intégré dans la guerre, tandis que le .le fichier properties est sur le serveur d'application (Tomcat dans ce cas particulier).

C'est très bien et permet de définir les différents crons en fonction de l'environnement (développement, intégration, production, ...).

maintenant, en exécutant cette application localement sur mon propre ordinateur, je ne souhaite pas que ces travaux soient exécutés. Y a-t-il un moyen d'écrire une expression cron qui ne se déclenche jamais?

58
demandé sur Community 2012-12-12 11:56:12

5 réponses

TL; DR

Dans le Quartz, le 1, vous pouvez utiliser ce cron: 59 59 23 31 12 ? 2099 (la dernière date de validité).

Dans Quartz 2, Vous pouvez utiliser ce cron: 0 0 0 1 1 ? 2200

en Utilisant une expression de loin dans le futur

a fait quelques tests rapides en utilisant 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()));
}

quand je fais String exp = "# 0 0 0 1 1 ?"; , le test isValid retourne false .

avec l'échantillon étant donné ci-dessus encore, le résultat est le suivant:

true
null

qui signifie:

  • l'expression est valide;
  • il n'y a pas de date à venir qui corresponde à cette expression.

pour que l'ordonnanceur accepte un déclencheur cron, cependant, ce dernier doit correspondre à une date future.

j'ai essayé plusieurs années et compris qu'une fois le l'année est au-dessus de 2300, Quartz semble ne plus se soucier (bien que je n'ai pas trouvé une mention à une valeur maximale pour l'année dans la documentation de Quartz 2 ). Il y a peut-être un moyen plus propre de le faire, mais cela satisfera mes besoins pour l'instant.

donc, à la fin, le cron que je propose est 0 0 0 1 1 ? 2200 .

Quartz 1 variante

noter que, dans Quartz 1, 2099 est le dernier valide année . Vous pouvez donc adapter votre expression cron pour utiliser suggestion de Maciej Matys : 59 59 23 31 12 ? 2099

Alternative: utiliser une date dans le passé

Arnaud Denoyelle suggère quelque chose de plus élégant, que mon test ci-dessus valide comme une expression correcte: au lieu de choisir une date dans un avenir lointain, choisissez-la dans un passé lointain:

0 0 0 1 1 ? 1970 (la première expression valide selon la documentation de Quartz).

cette solution ne fonctionne cependant pas.

hippofluff mis en évidence que Quartz détectera une expression dans le passé ne sera plus jamais exécuté et donc jeter une exception.

org.quartz.SchedulerException: Based on configured schedule, the given trigger will never fire.

cela semble avoir été en Quartz depuis longtemps .

Leçons apprises: le test n'est pas infaillible comme

cela souligne une faiblesse de mon test: dans le cas où vous voulez tester un CronExpression , se rappeler il doit avoir un nextValidTime 1 . Sinon, l'ordonnanceur auquel vous le passerez le rejettera simplement avec l'exception mentionnée ci-dessus.

je vous conseille d'adapter le code d'essai comme suit:

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."));

voilà: pas besoin de réfléchir, il suffit de lire la sortie.


1 C'est la partie que j'ai oubliée en testant la solution D'Arnaud, en me faisant passer pour un idiot et en prouvant que mon test n'était pas à ma portée.

46
répondu Chop 2018-07-31 09:41:48

techniquement, les valeurs valides pour le champ facultatif de L'année de Quartz sont 1970-2099, donc 2300 n'est pas une valeur attendue. Je suppose que vous vraiment avez besoin de faire ceci et votre version de Quartz tente d'imposer la syntaxe cron valide (jour 1-31, mois 1-12, et ainsi de suite).

j'utilise actuellement le code suivant dans Resque-scheduler for Rails, qui accepte les informations de programme dans le format crontab validé, pour créer un travail de test manuel-run-only:

cron: "0 5 31 2 *"

Le travail va attendre patiemment tôt le matin février 31 avant de courir. Pour un équivalent en Quartz crontrigger , essayez cette ligne ou une variante de celle-ci:

0 0 5 31 2 ?
33
répondu Eric Tjossem 2012-12-18 17:12:44

essayez celui-ci: 59 59 23 31 12 ? 2099

24
répondu Maciej Matys 2014-10-17 07:54:29

j'ai trouvé cela en essayant de résoudre un problème similaire - désactivant une expression cron - mais j'ai rencontré les mêmes problèmes d'exiger une date de programme valide pour l'avenir.

j'ai aussi frappé des problèmes en utilisant la syntaxe de 7 valeurs - ne peut pas spécifier une année dans le calendrier cron.

donc j'ai utilisé ceci: 0 0 3 ? 2 lun#5

La prochaine fois ce sera exécuter sont:

  1. lundi 29 février 2044 3: 00 AM
  2. lundi 29 février 2072 3: 00 AM
  3. lundi 29 février, 2112 3: 00 AM
  4. lundi 29 février 2140 3: 00 AM
  5. lundi 29 février 2168 3: 00 AM

donc, essentiellement, à toutes fins pratiques, il est désactivé. :)

Ah. Malédictions, cela ne fonctionnera que pour la syntaxe quartz scheduler - la syntaxe Spring CronTrigger ne permet pas MON#5 pour la cinquième lundi

donc la prochaine meilleure chose est 0 0 3 29 2 ? qui ne sera exécuté qu'à 3 heures du matin le 29 février (années bissextiles)

4
répondu mrmoosehead 2018-01-10 10:29:19

maintenant, en exécutant cette application localement sur mon propre ordinateur, je ne souhaite pas que ces travaux soient exécutés. Y a-t-il un moyen d'écrire une expression cron qui ne se déclenche jamais?

si vous voulez désactiver l'ordonnancement sur votre ordinateur, vous avez plusieurs façons d'y arriver.

tout d'abord, vous pouvez déplacer la configuration de Quartz vers une configuration @Profile et ne pas activer ce profil localement. Quartz ne commencerait pas du tout si le profil n'est pas actif.

une alternative est de configurer Quartz pour ne pas démarrer automatiquement. Il y a un SchedulerFactoryBean#setAutoStartup() que vous pouvez définir dans BeanPostProcessor enregistré dans un profil dev. Alors que ce fil est assez vieux, La Botte de printemps offre une alternative en enregistrant un SchedulerFactoryBeanCustomizer haricot pour faire la même chose.

1
répondu Stephane Nicoll 2018-08-08 09:42:37