Youcef Laidani Youcef Laidani - 22 days ago 11
Java Question

Timer java not stop showing result in Netbeans when Undeploy the application?

I do create a timer which start when i deploy my application, what i note is this timer not stop when i

Undeploy
my application?


  1. How can this happen, and show me the result in Output netbeans?

  2. Should i restart my server every time that i
    Undeploy
    my
    application?



Singleton

@Singleton
@Startup
public class StartWhenDeploy {

private static final int PERIOD = 3000;

@PostConstruct
public void init() {
System.out.println("I will set information to start my task");
Timer timer = new Timer();
timer.schedule(new TimerAction(1), new Date(), PERIOD);
}
}


TimerTask

public class TimerAction extends TimerTask {

public int nbrUsers;

public TimerAction(int nbrUsers) {
this.nbrUsers = nbrUsers;
}

@Override
public void run() {
System.out.println("This task is planified to execute at " + new Date());
System.out.println("Creation " + (createUser() ? "------------Success------------" : "------------Failed------------"));
}

public boolean createUser() {
try {
System.out.println("-------------->" + nbrUsers);
for (int i = 0; i < nbrUsers; i++) {
System.out.println("Create user >>>>" + i);
}
return true;
} catch (Exception e) {
System.out.println("Exception " + e);
return false;
}
}
}


It still show me the result like this in Output netbeans:

...
Infos: This task is planified to execute at Wed Nov 16 14:40:29 GMT+01:00 2016
Infos: -------------->1
Infos: Create user >>>>0
Infos: Creation ------------Success------------
...


Someone have an idea about this issue?

Thank you.

Answer

In GlassFish (in JavaEE in general), you should use the TimerService from the EJB specification for scheduling. I assume you are using java.util.Timer, which just runs in a separate thread. GlassFish does not know anything about the thread, so it cannot stop it with undeploy.

You should rewrite your Singleton to something like this:

@Singleton
@Startup
public class StartWhenDeploy {

    private static final int PERIOD = 3000;

    // Inject the TimerService into this EJB
    @Resource
    private TimerService timer;

    private TimerAction action;

    @PostConstruct
    public void init() {
        System.out.println("I will set information to start my task");
        // the action object is created before the timer
        action = new TimerAction(1);
        timer.createTimer(new Date(), PERIOD, "My timer");
    }

    // this method will be executed when the timer fires - it needs to wrap your `TimerAction` created once per this singleton instance (`TimerAction` does not have to extend `TimerTask` now)
    @Timeout
    public void runTimerAction() {
        action.run();
    }

}