Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java SpringBoot method still @Scheduled under wrong @Profile?

My application.properties file defines the default profile as spring.profiles.active=test and I have a method that I schedule like so:

  @Scheduled(initialDelay = 2500, fixedRate = 60 * 1000 * minutesRecheckRate)
  @Profile("loop")
  public void processingLoop() {
    System.out.println(Arrays.toString(env.getActiveProfiles()));
    //.. the rest is omitted for brevity.

To my understanding, under these circumstances I should never see this get called while running my unit-tests because I do not change the default profile. This turns out not to be the case, as this is still getting scheduled and I see the output

[test]

in my console despite my best efforts to prevent it. What is happening? Why is this still running even with a different active profile?

UPDATE: I can't give much more due to the fact this is a work-relevant application, but I'll give what I can.

The class is configured like so:

@Configuration
@EnableScheduling
public class BatchConfiguration {

The unit tests are all annotated like this:

@SpringApplicationConfiguration(classes = SpringBatchJsontestApplication.class)
public class SpringBatchJsontestApplicationTests extends AbstractTestNGSpringContextTests {

The main application class is this:

@SpringBootApplication
public class SpringBatchJsontestApplication {

None of them change anything else. There is no context.xml file, this is a SpringBoot application so everything is annotations only.


This is the end result that works very well for me

  @Profile("test")
  @Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public ScheduledAnnotationBeanPostProcessor scheduleBeanProcessorOverride() {
    logger.info("Test Profile is active, overriding ScheduledAnnotationBeanPostProcessor to prevent annotations from running during tests.");
    return new ScheduledAnnotationBeanPostProcessor() {
      @Override
      protected void processScheduled(Scheduled scheduled, Method method, Object bean) {
        logger.info(String.format("Preventing scheduling for %s, %s, %s", scheduled, method, bean.getClass().getCanonicalName()));
      }
    };
  }

Here is the POM configuration to trigger the testing profile, so I no longer have to do so explicitly in my application.properties.

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19</version>
    <configuration>
      <systemPropertyVariables>
        <spring.profiles.active>test</spring.profiles.active>
      </systemPropertyVariables>
    </configuration>
  </plugin>
like image 630
Paul Nelson Baker Avatar asked Oct 21 '25 11:10

Paul Nelson Baker


1 Answers

The @Profile annotation doesn't do anything for a regular method, nor a method annotated with @Scheduled. The javadoc states

The @Profile annotation may be used in any of the following ways:

  • as a type-level annotation on any class directly or indirectly annotated with @Component, including @Configuration classes
  • as a meta-annotation, for the purpose of composing custom stereotype annotations
  • as a method-level annotation on any @Bean method

The last case, in bold, is the only use of @Profile on a method.

If you want to enable the @Scheduled behavior under a specific profile, annotate the bean (definition) that contains it.

like image 126
Sotirios Delimanolis Avatar answered Oct 23 '25 00:10

Sotirios Delimanolis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!