3

我的目标是通过 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 时是这样。

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

4

1 回答 1

1

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

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

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

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

于 2017-06-19T14:19:29.257 回答