【问题标题】:Quartz-scheduled JSR-352 jobs on GlassFish won't startGlassFish 上 Quartz 计划的 JSR-352 作业无法启动
【发布时间】:2017-06-12 09:02:31
【问题描述】:

我的目标是通过 GlassFish 服务器上的 Quartz 调度程序启动 JSR-352 批处理作业,但有一个大问题。首先,这是我的代码。

我的 JSR-352 工作:

<job id="myJob" ...>
    <step id="myBatchlet">
        <batchlet ref="mypackage.MyBatchlet" />
    </step>
</job>

对应的Java代码:

public class MyBatchlet implements Batchlet {

    @Override
    public String process() throws Exception {
        System.out.println("Hello World!");
        return BatchStatus.COMPLETED.toString();
    }

    @Override
    public void stop() throws Exception {
    }

}

当我通过 servlet 在 GlassFish 4.0 b89 服务器上开始这项工作时,它运行良好:

public class StartJobServlet extends HttpServlet {

    private void processRequest(...) throws ... {
        long executionId = BatchRuntime.getJobOperator().start("myJob", new Properties());
        System.out.println("myJob started, execution ID = " + executionId);
    }

}

但现在我想使用 Quartz 2.2.3 调度器,所以我这样写了一个 Quartz 作业:

public class StartMyJob implements Job {

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        long executionId = BatchRuntime.getJobOperator().start("myJob", new Properties());
        System.out.println("myJob started, execution ID = " + executionId);
    }

}

我已经为这项工作配置了 Quartz 和触发器。

但是当 myJob 应该启动时,它仍然处于 STARTING 状态并且从未真正运行。
根据日志,实际启动批处理作业的com.ibm.jbatch.container.util.BatchWorkUnit::run 过程永远不会被调用,而在使用 servlet 时是这样。

编辑:我发现了其他人的类似问题(相同症状)there,但由于我没有 glassfish-web.xml 文件,因此给定的解决方案不适合。

【问题讨论】:

  • 它看起来更像是线程池问题而不是类加载器问题。由于您的工作从您的 servlet 运行良好,因此来自 Quartz 的路径似乎存在问题(假设您没有更改线程池配置)。我对 Glassfish 中的 Quartz 不太熟悉,也许您可​​以分享一些有关如何在服务器中获取 Quartz 作业控制的详细信息(例如 Quartz 是在服务器中运行还是远程运行?)。
  • 是的,我重新创建了同样的东西。如果我有任何东西会回复更多。
  • 我的示例失败的原因是 Quartz 使用自己的线程来启动 JSR 352 作业。我认为正在发生的事情是 A)Glassfish 似乎使用了 ManagedExecutorService 的某种风格来执行作业(传播 EE 上下文)但是 B)Quartz 正在使用的非托管线程上没有 EE 上下文。不确定是否值得深入研究 Quartz 和/或 Glassfish 配置以某种方式解决此问题,或者是否值得重新审视您的用例(例如,如果您要在 EE 中,您从 Quartz 中得到什么与说 EJB 计时器)无论如何应用程序)。希望能有所帮助。

标签: java jakarta-ee glassfish quartz-scheduler jsr352


【解决方案1】:

使用 Quartz 在 EE 服务器内的非托管线程上执行作业会导致使用各种 EE API 时出现问题,包括 Java Batch (JSR 352)。

您可以使用标准的 EE API,例如 ManagedScheduledExecutorService@Schedule 等来替换 Quartz。 (有很多教程和例子)。

我不是 Quartz 方面的专家,无法列出涉及 Quartz 的替代方案。看来,如果您可以使用 ManagedExecutorService 让 Quartz 线程运行,就可以解决问题。 This JIRA 建议将其添加到 Terracotta Quartz,但我不敢肯定。也许还有一种使用开源 Quartz 的方法,或者在服务器外部运行 Quartz(并远程进入 EJB 之类的托管线程?,不确定),或者甚至使用我不知道的配置选项。

如果有人可以提供更好的答案来阐明 Quartz 选项,那将会很有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 2014-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多