quartz online once makecron ejemplo day spring quartz-scheduler

spring - online - Quartz: Cron expresión que nunca se ejecutará



makecron (4)

Usando una expresión lejos en el futuro

Hizo algunas pruebas rápidas usando 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())); }

Cuando hago String exp = "# 0 0 0 1 1 ?"; , la prueba isValid devuelve false .

Con la muestra anterior, el resultado es el siguiente:

true null

Sentido:

  • la expresión es válida;
  • no hay una fecha próxima que coincida con esta expresión.

Sin embargo, para que el planificador acepte un desencadenador cron, este último debe coincidir con una fecha en el futuro.

Intenté varios años y descubrí que una vez que el año está por encima de 2300, parece que Quartz ya no se molesta (aunque no encontré una mención a un valor máximo para el año en la documentación de Quartz 2 ). Puede haber una forma más limpia de hacerlo, pero esto satisfará mis necesidades por ahora.

Entonces, al final, el cron que propongo es 0 0 0 1 1 ? 2200 0 0 0 1 1 ? 2200 .

Variante de cuarzo 1

Tenga en cuenta que, en Cuarzo 1, 2099 es el último año válido . Por lo tanto, puede adaptar su expresión cron para usar la sugerencia de Maciej Matys : 59 59 23 31 12 ? 2099 59 59 23 31 12 ? 2099

Alternativa: Usar una fecha en el pasado

Arnaud Denoyelle sugirió algo más elegante, que mi prueba anterior valida como una expresión correcta: en lugar de elegir una fecha en un futuro lejano, elígela en un pasado lejano:

0 0 0 1 1 ? 1970 0 0 0 1 1 ? 1970 (la primera expresión válida según la documentación de Quartz).

Esta solución no funciona, sin embargo.

hippofluff destacó que Quartz detectará una expresión en pasado que nunca se ejecutará nuevamente y por lo tanto lanzará una excepción.

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

Esto parece haber estado en Quartz durante mucho tiempo .

Lecciones aprendidas: la prueba no es infalible como lo es

Esto resalta una debilidad de mi prueba: en caso de que quiera probar un CronExpression , recuerde que debe tener un nextValidTime 1 . De lo contrario, el programador al que lo pasará simplemente lo rechazará con la excepción mencionada anteriormente.

Aconsejaría adaptar el código de prueba de la siguiente manera:

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

Ahí tienes: no necesitas pensar, solo lee la salida.

1 Esta es la parte que olvidé cuando probé la solución de Arnaud, haciéndome el tonto y demostrando que mi prueba no era a prueba de nada.

Sé que hay un duplicado here , que probablemente sea exactamente mi caso, aunque merecería una explicación mejor, que trataré de presentar aquí.

Trabajo con una aplicación web Java usando un contexto de aplicación Spring. En este contexto, definí los trabajos programados usando Quartz. Estos trabajos son activados por un cron definido en un archivo .properties.

El contexto Spring está incrustado en la guerra, mientras que el archivo .properties está en el servidor de aplicaciones (Tomcat en este caso particular).

Esto está bien y permite definir diferentes crones según el entorno (desarrollo, integración, producción, ...).

Ahora, cuando ejecuto esta aplicación localmente en mi propia computadora, no deseo que se ejecuten estos trabajos. ¿Hay alguna manera de escribir una expresión cron que nunca se disparará?


Encontré esto mientras trataba de resolver un problema similar, deshabilitando una expresión cron, pero me encontré con los mismos problemas de requerir una fecha de programación futura válida.

También toco problemas usando la sintaxis de 7 valores: no puedo especificar un año en la programación de cron.

Entonces usé esto: 0 0 3? 2 MON # 5

Las próximas veces que esto se ejecutará son:

  1. Lunes, 29 de febrero de 2044 3:00 a.m.
  2. Lunes, 29 de febrero de 2072 3:00 a.m.
  3. Lunes, 29 de febrero, 2112 3:00 a.m.
  4. Lunes, 29 de febrero, 2140 3:00 a.m.
  5. Lunes, 29 de febrero, 2168 3:00 a.m.

Entonces, esencialmente, a todos los efectos, está deshabilitado. :)

Ah. Maldiciones, esto solo funcionará para la sintaxis del planificador de Quartz: la sintaxis de Spring CronTrigger no permite MON # 5 para el quinto lunes

¿Entonces la próxima mejor cosa es 0 0 3 29 2? que solo se ejecutará a las 3 de la madrugada del 29 de febrero (años bisiestos)


Prueba esto: 59 59 23 31 12 ? 2099 59 59 23 31 12 ? 2099


Técnicamente, los valores válidos para el campo de año de cuarzo opcional son 1970-2099, por lo que 2300 no es un valor esperado. Supongo que realmente necesita hacer esto y su versión de Quartz intenta imponer la sintaxis cron válida (día 1-31, mes 1-12, etc.).

Actualmente estoy usando el siguiente código en Resque-scheduler for Rails, que acepta información de programación en formato crontab validado, para crear un trabajo de prueba de ejecución manual:

cron: "0 5 31 2 *"

El trabajo esperará pacientemente durante la mañana del 31 de febrero antes de correr. Para un equivalente en crontrigger Quartz , pruebe esta línea o alguna variante de la misma:

0 0 5 31 2 ?