User1
User1

Reputation: 127

How can I use an external configuration property to define the cron expression in the @Schedule annotation of an EJB?

I have a cron expression in my properties file but the schedule annotation won't take the property like it would in Spring with the Scheduled annotation.

In Spring you can do:

@Scheduled(cron = "${app.cronExpiredDepartures}")

I want to do the same with EJB. At this point I don't care if the timer is programmatic or automatic, I just want the easier way to be able to use a cron property in my timer.

I have tried to use the info attribute of the @Schedule annotation with no success:

    @Inject
    @ConfigProperty(name = "app.cronExpiredDepartures", defaultValue = "* * * * *")
    private String cronExpression;

    @Schedule(persistent = false, info = "app.cronExpiredDepartures")
    @Transactional
    public void checkExpiredDepartures() {

        System.out.println("checkExpiredDepartures executed");
        blabla
            }
        }
    }

This is my cron expression in my properties file:

app.cronExpiredDepartures="* * * * *"

Meaning:

Any minute, any hour, any day, any month, any day of the week

So: Execute every minute.

I have also tried using the programmatic approach with no results. The timeout method doesn't run:

@Stateless public class ExpirationWatch {

@Resource
private TimerService timerService;

@Inject
@ConfigProperty(name = "app.cronExpiredDepartures", defaultValue = "* * * * *")
private String cronExpression;


@PostConstruct
public void init() {
    ScheduleExpression schedule = new ScheduleExpression();

    String[] parts = cronExpression.split(" ");
    schedule
        .second("0")
        .minute(parts[0])
        .hour(parts[1])
        .dayOfMonth(parts[2])
        .month(parts[3])
        .dayOfWeek(parts[4]);

    timerService.createCalendarTimer(schedule, new TimerConfig("ExpirationWatchTimer", false));
}

@Timeout
@Transactional
public void checkExpiredDepartures()  {

    System.out.println("checkExpiredDepartures executed");
    
        }
    }
}

}

Upvotes: 0

Views: 18

Answers (1)

User1
User1

Reputation: 127

I found a way to make it work. It seems the problem was with the annotations. My EJB programmatic timer was not executing even if I changed it to a really simple case.

I used the annotation @Singleton instead of @Stateless (both can't be used) and @Startup like this:

@Singleton
@Startup
public class ExpirationWatch {

@Resource
private TimerService timerService;

@Inject
@ConfigProperty(name = "app.cronExpiredDepartures", defaultValue = "* * * * *")
private String cronExpression;


@PostConstruct
public void init() {
    ScheduleExpression schedule = new ScheduleExpression();

    String[] parts = cronExpression.split(" ");
    schedule
        .second("0")
        .minute(parts[0])
        .hour(parts[1])
        .dayOfMonth(parts[2])
        .month(parts[3])
        .dayOfWeek(parts[4]);

    timerService.createCalendarTimer(schedule, new TimerConfig("ExpirationWatchTimer", false));
}

@Timeout
@Transactional
public void checkExpiredDepartures()  {

    System.out.println("checkExpiredDepartures executed");
    
        }
    }
}

Upvotes: 0

Related Questions