我的目标是通过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时。
答案 0 :(得分: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选项,那将会有所帮助。