首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >按时间间隔运行Java EE CDI任务

按时间间隔运行Java EE CDI任务
EN

Stack Overflow用户
提问于 2021-01-10 08:55:43
回答 3查看 85关注 0票数 0

一旦我的应用程序(WAR)启动,我使用的是WildFly 21。任务应该在启动时初始化,并在某个时间间隔执行一些工作。

这个类在下面

代码语言:javascript
运行
复制
@ApplicationScoped
@ActivateRequestContext
public class TaskRunner {

 
  @Resource private ManagedScheduledExecutorService scheduler;

  @Inject private ScheduledFuture<?> TaskRunnerScheduler;

  private boolean initialized = false;

  private void init(@Observes @Initialized(ApplicationScoped.class) Object init) {

    if (initialized) return;

   
    initialized = true;
    try {
      // Execute at startup
      TaskRunner = scheduler.schedule(this::runSchedule, getSchedule());
    } catch (Throwable throwable) {

    }
  }

  private void runSchedule() {
//do some work
  }

  private Trigger getSchedule() {
    return new Trigger() {
      @Override
      public Date getNextRunTime(LastExecution lastExecutionInfo, Date taskScheduledTime) {
        return Date.from(
            ZonedDateTime.now().withSecond(0).withNano(0).plusHours("4").toInstant());
      }

      @Override
      public boolean skipRun(LastExecution lastExecutionInfo, Date scheduledRunTime) 
       {return false;}};
  }

}

在尝试部署应用程序时,我收到以下错误

代码语言:javascript
运行
复制
 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-6) MSC000001: Failed to start service jboss.deployment.unit."task-web.war".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."task-web.war".WeldStartService: Failed to start service
    at org.jboss.msc@1.4.12.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1731)
    at org.jboss.msc@1.4.12.Final//org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1559)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type ScheduledFuture<?> with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject private TaskRunner.TaskRunnerScheduler
  at TaskRunner.TaskRunnerScheduler(TaskRunner.java:0)

    at org.jboss.weld.core@3.1.5.Final//org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:378)
    at org.jboss.weld.core@3.1.5.Final//org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:290)
    at org.jboss.weld.core@3.1.5.Final//org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:143)
    at org.jboss.weld.core@3.1.5.Final//org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:164)
    at org.jboss.weld.core@3.1.5.Final//org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:526)
    at org.jboss.weld.core@3.1.5.Final//org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:64)
    at org.jboss.weld.core@3.1.5.Final//org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:62)
    at org.jboss.weld.core@3.1.5.Final//org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:62)
    at org.jboss.weld.core@3.1.5.Final//org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:55)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.JBossThread.run(JBossThread.java:513)

你知道这个错误的原因是什么吗?

EN

回答 3

Stack Overflow用户

发布于 2021-01-11 01:20:42

看起来你想每4个小时左右跑一次。我可以建议一个更简洁的实现吗?

代码语言:javascript
运行
复制
@Startup
@Singleton
public class MyScheduler {
    @PostConstruct
    private void runAtStartup() {
        // whatever makes sense here
    }

    @Schedule(hour = "*/4", persistent = false )
    private void runSomething() {
        // something here
    }
}

这会将一个EJB设置为在启动时运行(@Startup),说明它只有一个实例(@Singleton)。然后,它每4小时运行一次runSomething()方法。您可以查看Schedule Javadocs,因为还有许多其他方法可以运行它。如果以前只存在用于设置计时器的@PostConstruct方法,则可能需要也可能不需要。

persistent参数告诉Wildfly记住最后一次运行的时间,如果重新启动,则继续按该计划运行。如果您不关心您的方法是否在重启时再次运行,那么将这个值保留为false。

我唯一的警告是这个机制不能处理重叠。如果您使用此方法,并且在最后一个调度方法完成之前(在本例中为4小时后)运行新的调度方法,则可能会导致至少您的日志中出现错误,并且调度不会按预期的方式运行。

票数 1
EN

Stack Overflow用户

发布于 2021-01-13 04:50:06

只需从您的代码片段中删除(未使用) TaskRunnerScheduler字段即可。

票数 1
EN

Stack Overflow用户

发布于 2021-01-18 07:40:14

我找到了问题所在,它是下面一行中的一个打字错误

代码语言:javascript
运行
复制
 @Inject private ScheduledFuture<?> TaskRunnerScheduler;

正确的方法是不使用注入

代码语言:javascript
运行
复制
 private ScheduledFuture<?> TaskRunnerScheduler;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65649181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档