From e1f819d54515a55097ca01b33b2d2a677d4e053f Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Thu, 2 Mar 2023 14:44:29 +0100 Subject: [PATCH] Scheduler - detect scheduled methods of the same name on a class - fix #31547 --- .../ScheduledBusinessMethodItem.java | 4 +++ .../deployment/SchedulerProcessor.java | 12 +++++-- ...leScheduledMethodsWithTheSameNameTest.java | 36 +++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/MultipleScheduledMethodsWithTheSameNameTest.java diff --git a/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/ScheduledBusinessMethodItem.java b/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/ScheduledBusinessMethodItem.java index acce3bce521f4..b303fc18369e0 100644 --- a/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/ScheduledBusinessMethodItem.java +++ b/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/ScheduledBusinessMethodItem.java @@ -48,4 +48,8 @@ public boolean isNonBlocking() { return nonBlocking; } + public String getMethodDescription() { + return method.declaringClass().name() + "#" + method.name() + "()"; + } + } 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 22849d153a035..5cf66442f529b 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 @@ -12,9 +12,11 @@ import java.time.ZoneId; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.function.Function; @@ -192,17 +194,23 @@ void validateScheduledBusinessMethods(SchedulerConfig config, List validationErrors) { List errors = new ArrayList<>(); Map encounteredIdentities = new HashMap<>(); + Set methodDescriptions = new HashSet<>(); for (ScheduledBusinessMethodItem scheduledMethod : scheduledMethods) { + if (!methodDescriptions.add(scheduledMethod.getMethodDescription())) { + errors.add(new IllegalStateException("Multiple @Scheduled methods of the same name declared on the same class: " + + scheduledMethod.getMethodDescription())); + continue; + } MethodInfo method = scheduledMethod.getMethod(); if (Modifier.isAbstract(method.flags())) { errors.add(new IllegalStateException("@Scheduled method must not be abstract: " - + method.declaringClass().name() + "#" + method.name() + "()")); + + scheduledMethod.getMethodDescription())); continue; } if (Modifier.isPrivate(method.flags())) { errors.add(new IllegalStateException("@Scheduled method must not be private: " - + method.declaringClass().name() + "#" + method.name() + "()")); + + scheduledMethod.getMethodDescription())); continue; } diff --git a/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/MultipleScheduledMethodsWithTheSameNameTest.java b/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/MultipleScheduledMethodsWithTheSameNameTest.java new file mode 100644 index 0000000000000..5dea5442efe5b --- /dev/null +++ b/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/MultipleScheduledMethodsWithTheSameNameTest.java @@ -0,0 +1,36 @@ +package io.quarkus.scheduler.test; + +import jakarta.enterprise.inject.spi.DeploymentException; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.scheduler.Scheduled; +import io.quarkus.scheduler.ScheduledExecution; +import io.quarkus.test.QuarkusUnitTest; + +public class MultipleScheduledMethodsWithTheSameNameTest { + + @RegisterExtension + static final QuarkusUnitTest test = new QuarkusUnitTest() + .setExpectedException(DeploymentException.class) + .withApplicationRoot((jar) -> jar + .addClasses(BeanWithInvalidScheduledMethods.class)); + + @Test + public void test() throws InterruptedException { + } + + static class BeanWithInvalidScheduledMethods { + + @Scheduled(cron = "0/1 * * * * ?") + void foo() { + } + + @Scheduled(every = "10s") + void foo(ScheduledExecution execution) { + } + + } + +}