Hot questions for Using GlassFish in timer

Question:

I want to have a method run every day at 3am that will summarize a production database and insert into another database. I've seen examples of the Timer services with Java but I'm not sure that is what I am looking for. I want the program to execute on its own with me having to worry about it starting up at 3am do its work and go to sleep until 3am the next day so and so on. Any Links to pre-existing questions, blogs, or guides will be much appreciated(if there are any), thanks.


Answer:

You can try with java.util.Timer and java.util.TimerTask classes

Question:

Running a stock Glassfish or Payara Server there is a default application deployed called "ejb-timer-service-app" which includes a web frontend at http://localhost:8080/ejb-timer-service-app/timer

More information here: https://docs.oracle.com/cd/E18930_01/html/821-2418/beahw.html

Sadly the frontend is not reachable over the protected admin console (port 4848) but over the main host (port 8080 and 8181). So everyone knowing my server URL can access this page.

Is there a way to deactive the app (not the ejb-timer-service itself) or at least make the frontend-page no longer accessable (hide it) without some fancy firewall or loadbalancer configurations?


Answer:

Apparently there is currently no way to disable the application out of the box. I requested a new features for payara over at github: https://github.com/payara/Payara/issues/1803

Because the ejb-timer-service-app.war is required for the application server in order to provide the EJB timerservice it can't be deleted.

However I've created a workaround to at least disable the frontend part:

I did some quick tests locally on how to remove the frontend without damaging the EJB timer-service. Here is what I've changed inside the ${PAYARA_HOME}/glassfish/lib/install/applications/ejb-timer-service-app.war:

Delete file WEB-INF\sun-web.xml Delete file WEB-INF\web.xml Delete folder WEB-INF\classes\com

Shell commands:

zip -d ejb-timer-service-app.war "WEB-INF/sun-web.xml"
zip -d ejb-timer-service-app.war "WEB-INF/web.xml"
zip -d ejb-timer-service-app.war "WEB-INF/classes/com/*"

If the domain has been started before you also have to delete the folder glassfish\domains\domain1\applications\ejb-timer-service-app to clean up the already deployed frontend.

After a domain restart the servlet at http://localhost:8080/ejb-timer-service-app/timer is no longer available (HTTP 404) nevertheless the EJB timers are working properly

Question:

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();
    }

}