From 6c0873d2c4e94ef125eec5c026f140723084290a Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Thu, 22 Jul 2021 13:44:18 +0200 Subject: [PATCH] Dev UI - scheduler improvements - add option to pause/resume individual jobs with identity - add Scheduler#isPaused(identity) - show the configured values in the schedules table; e.g. "{cron.expr} configured as */5 * * * * ?" - fix links to config expressions in the docs --- .../main/asciidoc/scheduler-reference.adoc | 8 ++--- .../quarkus/quartz/test/PausedMethodTest.java | 6 ++++ .../quartz/test/PausedResumedMethodTest.java | 3 ++ .../quartz/runtime/QuartzScheduler.java | 31 +++++++++++++++++++ .../deployment/SchedulerProcessor.java | 15 +++++---- .../resources/dev-templates/embedded.html | 2 +- .../resources/dev-templates/schedules.html | 30 ++++++++++++++++-- .../dev-templates/tags/configVal.html | 1 + .../dev-templates/tags/scheduleInfo.html | 26 +++++++++++++--- .../scheduler/test/PausedMethodTest.java | 6 ++++ .../test/PausedResumedMethodTest.java | 3 ++ .../java/io/quarkus/scheduler/Scheduler.java | 23 +++++++++----- .../runtime/ScheduledMethodMetadata.java | 21 ++++++++++--- .../scheduler/runtime/SimpleScheduler.java | 15 +++++++++ .../SchedulerDevConsoleRecorder.java | 30 ++++++++++++++++++ .../runtime/util/SchedulerUtils.java | 6 ++-- .../DevConsoleSchedulerSmokeTest.java | 2 +- 17 files changed, 194 insertions(+), 34 deletions(-) create mode 100644 extensions/scheduler/deployment/src/main/resources/dev-templates/tags/configVal.html diff --git a/docs/src/main/asciidoc/scheduler-reference.adoc b/docs/src/main/asciidoc/scheduler-reference.adoc index 4a9d53d25f4b4..c4645e5996725 100644 --- a/docs/src/main/asciidoc/scheduler-reference.adoc +++ b/docs/src/main/asciidoc/scheduler-reference.adoc @@ -54,7 +54,7 @@ The syntax used in CRON expressions is controlled by the `quarkus.scheduler.cron The values can be `cron4j`, `quartz`, `unix` and `spring`. `quartz` is used by default. -The `cron` attribute supports <> including default values and nested +The `cron` attribute supports <> including default values and nested Property Expressions. (Note that "{property.path}" style expressions are still supported but don't offer the full functionality of Property Expressions.) @@ -98,7 +98,7 @@ So for example, `15m` can be used instead of `PT15M` and is parsed as "15 minute void every15Mins() { } ---- -The `every` attribute supports <> including default values and nested +The `every` attribute supports <> including default values and nested Property Expressions. (Note that `"{property.path}"` style expressions are still supported but don't offer the full functionality of Property Expressions.) .Interval Config Property Example @@ -132,7 +132,7 @@ Sometimes a possibility to specify an explicit id may come in handy. void myMethod() { } ---- -The `identity` attribute supports <> including default values and nested +The `identity` attribute supports <> including default values and nested Property Expressions. (Note that `"{property.path}"` style expressions are still supported but don't offer the full functionality of Property Expressions.) .Interval Config Property Example @@ -171,7 +171,7 @@ void everyTwoSeconds() { } NOTE: If `@Scheduled#delay()` is set to a value greater than zero the value of `@Scheduled#delayed()` is ignored. The main advantage over `@Scheduled#delay()` is that the value is configurable. -The `delay` attribute supports <> including default values and nested +The `delay` attribute supports <> including default values and nested Property Expressions. (Note that `"{property.path}"` style expressions are still supported but don't offer the full functionality of Property Expressions.) diff --git a/extensions/quartz/deployment/src/test/java/io/quarkus/quartz/test/PausedMethodTest.java b/extensions/quartz/deployment/src/test/java/io/quarkus/quartz/test/PausedMethodTest.java index fd8a80e9ed2f2..3e7ed9cba9fb0 100644 --- a/extensions/quartz/deployment/src/test/java/io/quarkus/quartz/test/PausedMethodTest.java +++ b/extensions/quartz/deployment/src/test/java/io/quarkus/quartz/test/PausedMethodTest.java @@ -1,12 +1,14 @@ package io.quarkus.quartz.test; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import javax.annotation.Priority; import javax.enterprise.event.Observes; +import javax.inject.Inject; import javax.interceptor.Interceptor; import org.jboss.shrinkwrap.api.ShrinkWrap; @@ -28,9 +30,13 @@ public class PausedMethodTest { private static final String IDENTITY = "myScheduled"; + @Inject + Scheduler scheduler; + @Test public void testPause() throws InterruptedException { assertFalse(Jobs.LATCH.await(3, TimeUnit.SECONDS)); + assertTrue(scheduler.isPaused(IDENTITY)); } static class Jobs { diff --git a/extensions/quartz/deployment/src/test/java/io/quarkus/quartz/test/PausedResumedMethodTest.java b/extensions/quartz/deployment/src/test/java/io/quarkus/quartz/test/PausedResumedMethodTest.java index 6f6512d93191d..f659f04ba072d 100644 --- a/extensions/quartz/deployment/src/test/java/io/quarkus/quartz/test/PausedResumedMethodTest.java +++ b/extensions/quartz/deployment/src/test/java/io/quarkus/quartz/test/PausedResumedMethodTest.java @@ -1,5 +1,6 @@ package io.quarkus.quartz.test; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.concurrent.CountDownLatch; @@ -34,8 +35,10 @@ public class PausedResumedMethodTest { @Test public void testPause() throws InterruptedException { + assertTrue(scheduler.isPaused(IDENTITY)); scheduler.resume(IDENTITY); assertTrue(Jobs.LATCH.await(3, TimeUnit.SECONDS)); + assertFalse(scheduler.isPaused(IDENTITY)); } static class Jobs { diff --git a/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzScheduler.java b/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzScheduler.java index 5dd99fee69ebb..b027370bfaac9 100644 --- a/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzScheduler.java +++ b/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzScheduler.java @@ -3,6 +3,7 @@ import java.time.Instant; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.OptionalLong; @@ -34,6 +35,7 @@ import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.SimpleScheduleBuilder; +import org.quartz.Trigger.TriggerState; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; import org.quartz.simpl.InitThreadContextClassLoadHelper; @@ -254,6 +256,35 @@ public void pause(String identity) { } } + @Override + public boolean isPaused(String identity) { + Objects.requireNonNull(identity); + if (identity.isEmpty()) { + return false; + } + try { + List triggers = scheduler + .getTriggersOfJob(new JobKey(SchedulerUtils.lookUpPropertyValue(identity), Scheduler.class.getName())); + if (triggers.isEmpty()) { + return false; + } + for (org.quartz.Trigger trigger : triggers) { + try { + if (scheduler.getTriggerState(trigger.getKey()) != TriggerState.PAUSED) { + return false; + } + } catch (SchedulerException e) { + LOGGER.warnf("Cannot obtain the trigger state for %s", trigger.getKey()); + return false; + } + } + return true; + } catch (SchedulerException e1) { + LOGGER.warnf(e1, "Cannot obtain triggers for job with identity %s", identity); + return false; + } + } + @Override public void resume() { if (!enabled) { diff --git a/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java b/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java index eff47c990383f..3adaec79a5daf 100644 --- a/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java +++ b/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java @@ -238,8 +238,8 @@ public String apply(String name) { schedules.add(annotationProxy.builder(scheduled, Scheduled.class).build(classOutput)); } metadata.setSchedules(schedules); - metadata.setMethodDescription( - scheduledMethod.getMethod().declaringClass() + "#" + scheduledMethod.getMethod().name()); + metadata.setDeclaringClassName(scheduledMethod.getMethod().declaringClass().toString()); + metadata.setMethodName(scheduledMethod.getMethod().name()); scheduledMetadata.add(metadata); } @@ -251,16 +251,15 @@ public String apply(String name) { } @BuildStep - public void devConsoleInfo(BuildProducer infos) { + @Record(value = STATIC_INIT, optional = true) + public DevConsoleRouteBuildItem devConsole(BuildProducer infos, + SchedulerDevConsoleRecorder recorder) { infos.produce(new DevConsoleRuntimeTemplateInfoBuildItem("schedulerContext", new BeanLookupSupplier(SchedulerContext.class))); infos.produce(new DevConsoleRuntimeTemplateInfoBuildItem("scheduler", new BeanLookupSupplier(Scheduler.class))); - } - - @BuildStep - @Record(value = STATIC_INIT, optional = true) - DevConsoleRouteBuildItem invokeEndpoint(SchedulerDevConsoleRecorder recorder) { + infos.produce(new DevConsoleRuntimeTemplateInfoBuildItem("configLookup", + recorder.getConfigLookup())); return new DevConsoleRouteBuildItem("schedules", "POST", recorder.invokeHandler()); } diff --git a/extensions/scheduler/deployment/src/main/resources/dev-templates/embedded.html b/extensions/scheduler/deployment/src/main/resources/dev-templates/embedded.html index eb3056710e716..67aec7ee1b7f6 100644 --- a/extensions/scheduler/deployment/src/main/resources/dev-templates/embedded.html +++ b/extensions/scheduler/deployment/src/main/resources/dev-templates/embedded.html @@ -1,3 +1,3 @@ - Schedules {info:schedulerContext.scheduledMethods.size()} + Scheduled Methods {info:schedulerContext.scheduledMethods.size()} diff --git a/extensions/scheduler/deployment/src/main/resources/dev-templates/schedules.html b/extensions/scheduler/deployment/src/main/resources/dev-templates/schedules.html index 1c27da7c45c97..f28095a77a1fa 100644 --- a/extensions/scheduler/deployment/src/main/resources/dev-templates/schedules.html +++ b/extensions/scheduler/deployment/src/main/resources/dev-templates/schedules.html @@ -1,5 +1,29 @@ -{#include main} - {#title}Schedules{/title} +{#include main fluid=true} + {#title}Scheduled Methods{/title} + {#style} + span.app-class { + cursor:pointer; + color:blue; + text-decoration:underline; + } + {/style} + {#script} + $(document).ready(function(){ + if (!ideKnown()) { + return; + } + $(".class-candidate").each(function() { + var className = $(this).text(); + if (appClassLang(className)) { + $(this).addClass("app-class"); + } + }); + + $(".app-class").on("click", function() { + openInIDE($(this).text()); + }); + }); + {/script} {#body} {#if info:scheduler.running}
@@ -40,7 +64,7 @@ {/if} - {scheduledMethod.methodDescription} + {scheduledMethod.declaringClassName}#{scheduledMethod.methodName}() diff --git a/extensions/scheduler/deployment/src/main/resources/dev-templates/tags/configVal.html b/extensions/scheduler/deployment/src/main/resources/dev-templates/tags/configVal.html new file mode 100644 index 0000000000000..34efcea830b08 --- /dev/null +++ b/extensions/scheduler/deployment/src/main/resources/dev-templates/tags/configVal.html @@ -0,0 +1 @@ +{#set val=info:configLookup.apply(it)}{#if val == it}{it}{#else}{it} configured as {val}{/if}{/set} \ No newline at end of file diff --git a/extensions/scheduler/deployment/src/main/resources/dev-templates/tags/scheduleInfo.html b/extensions/scheduler/deployment/src/main/resources/dev-templates/tags/scheduleInfo.html index c124de5fa6d72..5bc96c5e7f65f 100644 --- a/extensions/scheduler/deployment/src/main/resources/dev-templates/tags/scheduleInfo.html +++ b/extensions/scheduler/deployment/src/main/resources/dev-templates/tags/scheduleInfo.html @@ -1,10 +1,28 @@ {#if it.cron} - {it.cron} + {#configVal it.cron /} {#else} - Every {it.every} + Every {#configVal it.every /} +{/if} +{#if it.identity} + with identity {#configVal it.identity /} + {#if info:scheduler.running} + {#if info:scheduler.isPaused(it.identity)} + + + + +
+ {#else} +
+ + + +
+ {/if} + {/if} {/if} {#if it.delay > 0} (with delay {it.delay} {it.delayUnit.toString.toLowerCase}) {#else if !it.delayed.empty} - (delayed for {it.delayed}) -{/if} \ No newline at end of file + (delayed for {#configVal it.delayed /}) +{/if} diff --git a/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/PausedMethodTest.java b/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/PausedMethodTest.java index 8fe9e99dc9f3e..8dc4f8f9c3df8 100644 --- a/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/PausedMethodTest.java +++ b/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/PausedMethodTest.java @@ -1,12 +1,14 @@ package io.quarkus.scheduler.test; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import javax.annotation.Priority; import javax.enterprise.event.Observes; +import javax.inject.Inject; import javax.interceptor.Interceptor; import org.jboss.shrinkwrap.api.ShrinkWrap; @@ -28,9 +30,13 @@ public class PausedMethodTest { private static final String IDENTITY = "myScheduled"; + @Inject + Scheduler scheduler; + @Test public void testPause() throws InterruptedException { assertFalse(Jobs.LATCH.await(3, TimeUnit.SECONDS)); + assertTrue(scheduler.isPaused(IDENTITY)); } static class Jobs { diff --git a/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/PausedResumedMethodTest.java b/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/PausedResumedMethodTest.java index 9dd24524caa82..e170fe3b0e95d 100644 --- a/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/PausedResumedMethodTest.java +++ b/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/PausedResumedMethodTest.java @@ -1,5 +1,6 @@ package io.quarkus.scheduler.test; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.concurrent.CountDownLatch; @@ -34,8 +35,10 @@ public class PausedResumedMethodTest { @Test public void testPause() throws InterruptedException { + assertTrue(scheduler.isPaused(IDENTITY)); scheduler.resume(IDENTITY); assertTrue(Jobs.LATCH.await(3, TimeUnit.SECONDS)); + assertFalse(scheduler.isPaused(IDENTITY)); } static class Jobs { diff --git a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/Scheduler.java b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/Scheduler.java index d279c403f8688..3f49b57968de9 100644 --- a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/Scheduler.java +++ b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/Scheduler.java @@ -3,8 +3,6 @@ /** * The container provides a built-in bean with bean type {@link Scheduler} and qualifier * {@link javax.enterprise.inject.Default}. - * - * @author Martin Kouba */ public interface Scheduler { @@ -14,9 +12,10 @@ public interface Scheduler { void pause(); /** - * Pause a specific trigger. Identity must not be null and non-existent identity results in no-op. + * Pause a specific job. Identity must not be null and non-existent identity results in no-op. * - * @param identity see {@link Scheduled#identity()} + * @param identity + * @see Scheduled#identity() */ void pause(String identity); @@ -26,14 +25,24 @@ public interface Scheduler { void resume(); /** - * Resume a specific trigger. Identity must not be null and non-existent identity results in no-op. + * Resume a specific job. Identity must not be null and non-existent identity results in no-op. * - * @param identity see {@link Scheduled#identity()} + * @param identity + * @see Scheduled#identity() */ void resume(String identity); /** - * @return if a scheduler is running the triggers are fired and jobs are executed. + * Identity must not be null and {@code false} is returned for non-existent identity. + * + * @param identity + * @return {@code true} if the job with the given identity is paused, {@code false} otherwise + * @see Scheduled#identity() + */ + boolean isPaused(String identity); + + /** + * @return {@code true} if a scheduler is running the triggers are fired and jobs are executed, {@code false} otherwise */ boolean isRunning(); diff --git a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/ScheduledMethodMetadata.java b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/ScheduledMethodMetadata.java index 8580d8c234287..565f2fb9664d1 100644 --- a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/ScheduledMethodMetadata.java +++ b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/ScheduledMethodMetadata.java @@ -7,7 +7,8 @@ public class ScheduledMethodMetadata { private String invokerClassName; - private String methodDescription; + private String declaringClassName; + private String methodName; private List schedules; public String getInvokerClassName() { @@ -19,11 +20,23 @@ public void setInvokerClassName(String invokerClassName) { } public String getMethodDescription() { - return methodDescription; + return declaringClassName + "#" + methodName; } - public void setMethodDescription(String description) { - this.methodDescription = description; + public String getDeclaringClassName() { + return declaringClassName; + } + + public void setDeclaringClassName(String declaringClassName) { + this.declaringClassName = declaringClassName; + } + + public String getMethodName() { + return methodName; + } + + public void setMethodName(String methodName) { + this.methodName = methodName; } public List getSchedules() { diff --git a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/SimpleScheduler.java b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/SimpleScheduler.java index 1fbc8065f0b15..3c2041e26da83 100644 --- a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/SimpleScheduler.java +++ b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/SimpleScheduler.java @@ -166,6 +166,21 @@ public void pause(String identity) { } } + @Override + public boolean isPaused(String identity) { + Objects.requireNonNull(identity); + if (identity.isEmpty()) { + return false; + } + String parsedIdentity = SchedulerUtils.lookUpPropertyValue(identity); + for (ScheduledTask task : scheduledTasks) { + if (parsedIdentity.equals(task.trigger.id)) { + return !task.trigger.isRunning(); + } + } + return false; + } + @Override public void resume() { if (!enabled) { diff --git a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/devconsole/SchedulerDevConsoleRecorder.java b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/devconsole/SchedulerDevConsoleRecorder.java index bcf5e6a3ffdfa..0c24170507b80 100644 --- a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/devconsole/SchedulerDevConsoleRecorder.java +++ b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/devconsole/SchedulerDevConsoleRecorder.java @@ -1,6 +1,8 @@ package io.quarkus.scheduler.runtime.devconsole; import java.time.Instant; +import java.util.function.Function; +import java.util.function.Supplier; import org.jboss.logging.Logger; @@ -14,6 +16,7 @@ import io.quarkus.scheduler.runtime.ScheduledInvoker; import io.quarkus.scheduler.runtime.ScheduledMethodMetadata; import io.quarkus.scheduler.runtime.SchedulerContext; +import io.quarkus.scheduler.runtime.util.SchedulerUtils; import io.vertx.core.Handler; import io.vertx.core.MultiMap; import io.vertx.ext.web.RoutingContext; @@ -23,6 +26,16 @@ public class SchedulerDevConsoleRecorder { private static final Logger LOG = Logger.getLogger(SchedulerDevConsoleRecorder.class); + public Supplier> getConfigLookup() { + return new Supplier>() { + + @Override + public Function get() { + return SchedulerUtils::lookUpPropertyValue; + } + }; + } + public Handler invokeHandler() { // the usual issue of Vert.x hanging on to the first TCCL and setting it on all its threads final ClassLoader currentCl = Thread.currentThread().getContextClassLoader(); @@ -44,6 +57,22 @@ protected void handlePost(RoutingContext ctx, MultiMap form) throws Exception { LOG.info("Scheduler resumed via Dev UI"); flashMessage(ctx, "Scheduler resumed"); } + } else if ("pauseJob".equals(action)) { + Scheduler scheduler = Arc.container().instance(Scheduler.class).get(); + String identity = form.get("identity"); + if (identity != null && !scheduler.isPaused(identity)) { + scheduler.pause(identity); + LOG.infof("Scheduler paused job with identity '%s' via Dev UI", identity); + flashMessage(ctx, "Job with identity " + identity + " paused"); + } + } else if ("resumeJob".equals(action)) { + Scheduler scheduler = Arc.container().instance(Scheduler.class).get(); + String identity = form.get("identity"); + if (identity != null && scheduler.isPaused(identity)) { + scheduler.resume(identity); + LOG.infof("Scheduler resumed job with identity '%s'via Dev UI", identity); + flashMessage(ctx, "Job with identity " + identity + " resumed"); + } } else { String name = form.get("name"); SchedulerContext context = Arc.container().instance(SchedulerContext.class).get(); @@ -58,6 +87,7 @@ public void run() { ScheduledInvoker invoker = context .createInvoker(metadata.getInvokerClassName()); invoker.invoke(new DevModeScheduledExecution()); + LOG.infof("Invoked scheduled method %s via Dev UI", name); } catch (Exception e) { LOG.error( "Unable to invoke a @Scheduled method: " diff --git a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/util/SchedulerUtils.java b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/util/SchedulerUtils.java index 5e23aff1f14a0..312507759f027 100644 --- a/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/util/SchedulerUtils.java +++ b/extensions/scheduler/runtime/src/main/java/io/quarkus/scheduler/runtime/util/SchedulerUtils.java @@ -67,7 +67,7 @@ public static boolean isOff(String value) { * @return the resolved property value. */ public static String lookUpPropertyValue(String propertyValue) { - String value = propertyValue.trim(); + String value = propertyValue.stripLeading(); if (!value.isEmpty() && isConfigValue(value)) { value = resolvePropertyExpression(adjustExpressionSyntax(value)); } @@ -97,7 +97,9 @@ private static String adjustExpressionSyntax(String val) { * Adapted from {@link io.smallrye.config.ExpressionConfigSourceInterceptor} */ private static String resolvePropertyExpression(String expr) { - final Config config = ConfigProviderResolver.instance().getConfig(); + // Force the runtime CL in order to make the DEV UI page work + final ClassLoader cl = SchedulerUtils.class.getClassLoader(); + final Config config = ConfigProviderResolver.instance().getConfig(cl); final Expression expression = Expression.compile(expr, LENIENT_SYNTAX, NO_TRIM); final String expanded = expression.evaluate(new BiConsumer, StringBuilder>() { @Override diff --git a/integration-tests/devmode/src/test/java/io/quarkus/test/devconsole/DevConsoleSchedulerSmokeTest.java b/integration-tests/devmode/src/test/java/io/quarkus/test/devconsole/DevConsoleSchedulerSmokeTest.java index fdfae4c6dd863..0b9b006e81d14 100644 --- a/integration-tests/devmode/src/test/java/io/quarkus/test/devconsole/DevConsoleSchedulerSmokeTest.java +++ b/integration-tests/devmode/src/test/java/io/quarkus/test/devconsole/DevConsoleSchedulerSmokeTest.java @@ -26,7 +26,7 @@ public class DevConsoleSchedulerSmokeTest { public void testScheduler() { RestAssured.get("q/dev") .then() - .statusCode(200).body(Matchers.containsString("Schedules")); + .statusCode(200).body(Matchers.containsString("Scheduled Methods")); RestAssured.get("q/dev/io.quarkus.quarkus-scheduler/schedules") .then() .statusCode(200).body(Matchers.containsString("Scheduler is running"));