0

I need to stop and start all methods annotated with @Schedule in my EJBs classes.

For example I would like to stop and after few minutes restart doIt() method in that EJB class :

@Stateless
public class MySchedule {

  @Schedule(second = "*/15", minute = "*", hour = "*", persistent = false)
  public void doIt(){
    // do anything ...
  }

}

I tried to use EJB Interceptors , like this code :

@Stateless
public class MySchedule {

  @Schedule(second = "*/15", minute = "*", hour = "*", persistent = false)
  @Interceptors(MyInterceptor.class)
  public void doIt(){
    // do anything ...
  }
}

public class MyInterceptor{
         @AroundInvoke
         public Object intercept(){
            System.out.println(" Schedule Intercepted");  
            Object result = context.proceed();
         }
}

But intercept method never fired by @Schedule

Anderson Rossi
  • 493
  • 8
  • 21
  • Possible duplicate of [Possible to change ejb parameter at runtime for @Schedule annotation?](http://stackoverflow.com/questions/8320055/possible-to-change-ejb-parameter-at-runtime-for-schedule-annotation) – Gimby Mar 22 '17 at 16:02

1 Answers1

0

What you can do is to have a "Container" class with all of the classes annotated with @Scheduled. However, the problem with breaking/exit a method would rely on a condition/variable that keeps the code running or emits a signal of stop.

I'd do something like:

@Stateless
public class MySchedule implements Schedulable{
    boolean shouldRun = true;

    //This method should be present in the Schedulable interface
    @Override
    public synchronized boolean shouldBeRunning(boolean shouldRun){
      this.shouldRun = shouldRun;
    }

    //This method should also be in the Schedulable interface, so
    //you can invoke it wherever you need it.
    @Override
    @Schedule(second = "*/15", minute = "*", hour = "*", persistent = false)
    public void doIt(){
       /* If it runs a loop, you can break it like this: */
       while(shouldRun){
           //do anything
       }

       /* Otherwise you can break functionality of doIt and verify in each step: */
       if(shouldRun){
           //do anything step 1
       }

       if(shouldRun){
           //do anything step 2
       }

       if(shouldRun){
           //do anything step 3
       }
    }
}

The "Container" class:

@Named
public class SchedulableContainer{
    @EJB
    MySchedule mySchedule;

    @EJB
    MyOtherSchedule myOtherSchedule;

    private Schedulable[] schedulables;

    @PostConstruct
    void initSchedulables(){
       schedulables = new Schedulable[]{ sched, sched2 };
    }

    void toggleSchedulables(boolean shouldRun){
        for(Schedulable sched: schedulables){
            sched.shouldBeRunning(shouldRun);
        }
    }

    public void stopSchedulables(){
        this.toggleSchedulables(false);
    }

    public void restartSchedulables(){
        this.toggleSchedulables(true);

        //Here you could read a property that tells you
        //how much should you delay to trigger MySchedule#doIt
        //again.
    }
}
Omar
  • 689
  • 3
  • 16
  • Thanks Omar. But I would like to use less code. I tried to use EJB Interceptors but my Interceptors not fired when my method annotated with @Schedule are executed. – Anderson Rossi Mar 23 '17 at 18:27
  • @AndersonRossi update the code with interceptors, maybe someone with fresh eyes could help you. However, with Interceptors you still have the problem of how to "exit" the method. – Omar Mar 23 '17 at 19:47