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 a5b314107ad2b..5751a086d5c46 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 @@ -11,9 +11,11 @@ import java.time.Duration; 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; @@ -191,17 +193,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..2edadd011e600 --- /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 javax.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) { + } + + } + +}