如何延迟ManagedScheduledExecutorService直到容器未被挂起?

时间:2018-03-07 10:23:46

标签: java-ee scheduler wildfly-11

我正在研究在javax.enterprise.concurrent.ManagedScheduledExecutorService上使用WildFly Full 11.0.0.Final (WildFly Core 3.0.8.Final)

我的启动EJB类似于

import java.time.LocalTime;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.enterprise.concurrent.ManagedScheduledExecutorService;

@Startup
@Singleton
public class Scheduler {

    static final long INITIAL_DELAY = 0L;
    static final long PERIOD = 2L;

    @Resource
    ManagedScheduledExecutorService scheduler;

    @PostConstruct
    public void init() {
        this.scheduler.scheduleAtFixedRate(this::invokePeriodically, INITIAL_DELAY, PERIOD, TimeUnit.SECONDS);
    }

    public void invokePeriodically() {
        System.out.println("@@@@@@@@@@ - Don't use sout in prod " + LocalTime.now());
    }

}

在服务器启动时,我看到以下消息: -

10:15:26,022 ERROR [org.jboss.as.ee] (EE-ManagedScheduledExecutorService-default-Thread-1) WFLYEE0110: 
Failed to run scheduled task: java.lang.IllegalStateException: 
WFLYEE0111: Cannot run scheduled task com.research.Scheduler$$Lambda$932/1222053658@1b50d7a0 as container is suspended
    at org.jboss.as.ee.concurrent.ControlPointUtils$ControlledScheduledRunnable.run(ControlPointUtils.java:164)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
    at org.glassfish.enterprise.concurrent.internal.ManagedScheduledThreadPoolExecutor$ManagedScheduledFutureTask.access$201(ManagedScheduledThreadPoolExecutor.java:383)
    at org.glassfish.enterprise.concurrent.internal.ManagedScheduledThreadPoolExecutor$ManagedScheduledFutureTask.run(ManagedScheduledThreadPoolExecutor.java:534)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    at org.glassfish.enterprise.concurrent.ManagedThreadFactoryImpl$ManagedThread.run(ManagedThreadFactoryImpl.java:250)
    at org.jboss.as.ee.concurrent.service.ElytronManagedThreadFactory$ElytronManagedThread.run(ElytronManagedThreadFactory.java:78)

当我增加初始延迟时

static final long INITIAL_DELAY = 60L;

服务器启动是"清理"。

我是否可以使用任何可用的机制/技术(除了猜测我的初始延迟应该是多长时间)以便始终获得干净的服务器启动并尽快安排我的EJB?

2 个答案:

答案 0 :(得分:1)

为此,最好使用EJB计时器。在EJB投入使用之前,保证服务器不会触发计时器方法。

您可以在javax.ejb.TimerService验证用于创建计时器的API。

请注意,如果您创建持久性计时器,那么当您重新启动服务器时,服务器将尝试“赶上”错过的计时。

如果它只是一个周期性任务,那么就不要创建持久定时器。

答案 1 :(得分:1)

回答这个问题有点迟了,但是您可以使用内置的EE注释:@Schedule,而不是依赖于其他API,方法声明上方。它提供了在内部确定超时和持久性的功能。