6

I have the following singleton which should be executed when the web application starts but it does not, and the scheduled task does not run either.

@Singleton
@Startup
public class Scheduler {

    private static int count = 0;

    @PostConstruct
    public void onStartup() {
        System.out.println("Initialization success.");
    }

   @Schedule(second="*/10", minute="*", hour="*")
   public void execute() {
      System.out.println("its running count..."+count);
      count++;
   }
}

I am using Glassfish server 3.1.2.

EDIT

The startup method is now being executed but the schedule method does not run.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Paul Blundell
  • 1,857
  • 4
  • 22
  • 27
  • Can you show the import for the Singleton annotation? – perissf Mar 20 '13 at 10:36
  • 1
    Hi. it is: import javax.ejb.Singleton; – Paul Blundell Mar 20 '13 at 10:40
  • Do you see any errors / logs from GlassFish during (re)deployment? – perissf Mar 20 '13 at 10:45
  • No errors. Nothing related to this anyway. Does the location of the singleton make a difference? I currently have it in a .util package. Struggling to find what else could be wrong. – Paul Blundell Mar 20 '13 at 10:48
  • The location doesn't matter. What logs do you see when (re)deploying? Add them to the original question with the "edit" button – perissf Mar 20 '13 at 11:00
  • I checked the logs again and this time the onStartup method showed up so this being executed just fine. Bu the schedule method does not run. Any ideas? ... just to add I have never set up the scheduling on this before so unsure how it works. – Paul Blundell Mar 20 '13 at 11:09
  • 1
    maybe my answer here applies. http://stackoverflow.com/questions/13092567/automatic-ejb-timer-on-glassfish-server-not-triggering/13102822#13102822 – Aksel Willgert Mar 20 '13 at 11:49
  • Thank you Aksel. The persistent=false was the issue. – Paul Blundell Mar 20 '13 at 12:35

4 Answers4

11

My problem was that I used the wrong Singleton class, not javax.inject.Singleton but javax.ejb.Singleton

Jojo
  • 153
  • 1
  • 5
  • I had exactly the same problem right now, it was driving me nuts until I realized that the wrong Singleton annotation was imported. – Peter Walser Apr 06 '16 at 10:52
  • 2
    Which of the two classes should it be? – Albert Hendriks Jan 24 '18 at 11:14
  • I agree Peter, it's hard to tell from the comment! – nettie Aug 10 '18 at 16:24
  • This was my error as well. For a complete explanation of how to create a scheduler using a singleton in Java EE/Jarkata EE see https://stackoverflow.com/a/7499769/1090666. Just make sure that when you do, you import the correct Singleton class. – Mike Ryan Mar 13 '19 at 17:32
  • I was having the same issue. You must use `javax.ejb.Singleton` and `javax.ejb.Startup` for it to work. – Alexander Nov 04 '21 at 10:35
5

Adding another answer as there was some questions on Boreded's own answer.

The reason why setting persistence=false solved the problem is likely due to that persistent timers are not re-created if already existing when keepstate is set to true.

you should see the following in the log

INFO: keepstate is true and will not create new auto timers during deployment.

I think my answer here (together with Roland Tiefenbrunner's answer on same question) covers the issue somewhat well.

Community
  • 1
  • 1
Aksel Willgert
  • 11,367
  • 5
  • 53
  • 74
  • No. Normally, the timer is invoked with keepstate true as well as false, with persistent true as well as false. – perissf Mar 20 '13 at 19:42
  • The other answer given in the related question seems reasonable. Do you get any derby errors during GF startup? – perissf Mar 20 '13 at 19:52
  • Well sure the timer still fires, but what I think happens here is that first a timer without trace is deployed. So when you later change your timer to include the output-trace, it is not deployed. Changing keep-state or making the timer non-persistent redeployes the new timer. – Aksel Willgert Mar 20 '13 at 20:07
3

Also watch out for the default values of the annotation. Hour, minute and second default to 0 NOT *, whereas the others default to * , so e.g. @Schedule(minute = "*/20", persistent = false) will only fire at 20 + 40 mins past midnight.

@Target(value=METHOD)
@Retention(value=RUNTIME)
public @interface Schedule {
   String dayOfMonth() default "*";

   String dayOfWeek() default "*";

   String hour() default "0";

   String info() default "";

   String minute() default "0";

   String month() default "*";

   boolean persistent() default true;

   String second() default "0";

   String timezone() default "";

   String year() default "*";
}
Jon Vaughan
  • 2,058
  • 1
  • 18
  • 11
1

For anyone else with a similar issue adding the following fixed my problem:

persistent=false

So my schedule annotation is now

@Schedule(second="*/10", minute="*", hour="*", persistent=false)
Paul Blundell
  • 1,857
  • 4
  • 22
  • 27
  • 7
    The code exposed in the question works well without putting persistence=false. If this solution really solves the problem, it is accidentally hiding your real problem – perissf Mar 20 '13 at 17:35