You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus JBeret:作业完成后能否获取JobContext?

在Quarkus JBeret集成测试中获取JobContext的transientData

直接通过JobOperator获取的JobExecution是作业的持久化元数据,并不包含运行时的JobContext实例——JobContext是作业执行过程中的上下文对象,仅在作业运行时可访问。要测试transientData里的值,需要在作业执行阶段捕获JobContext,并将数据传递到测试代码中,具体可以通过自定义JobListener实现:

步骤1:编写测试用JobListener

创建一个JobListener实现类,注入JobContext后,将transientData存储到线程安全的容器中,关联对应的作业执行ID:

import jakarta.batch.api.listener.JobListener;
import jakarta.batch.runtime.context.JobContext;
import jakarta.inject.Inject;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ApplicationScoped
public class TestJobListener implements JobListener {
    @Inject
    JobContext jobContext;

    // 存储作业执行ID对应的transientData,线程安全容器适配JBeret的多线程执行
    public static final Map<Long, Map<String, Object>> jobTransientData = new ConcurrentHashMap<>();

    @Override
    public void beforeJob() throws Exception {
        // 若需要作业启动时的transientData,在此存储
        jobTransientData.put(jobContext.getExecutionId(), jobContext.getTransientUserData());
    }

    @Override
    public void afterJob() throws Exception {
        // 若需要作业执行完成后的最终transientData,在此更新
        jobTransientData.put(jobContext.getExecutionId(), jobContext.getTransientUserData());
    }
}

步骤2:在作业XML中配置Listener

将自定义的TestJobListener添加到你的作业配置XML中,确保作业执行时会触发该监听器:

<job id="your-target-job" xmlns="http://xmlns.jcp.org/xml/ns/javaee">
    <listeners>
        <listener ref="testJobListener"/>
    </listeners>
    <!-- 原有的Step配置 -->
    <step id="your-step">
        <!-- Step具体定义 -->
    </step>
</job>

步骤3:在测试中获取并验证transientData

启动作业后,先等待作业执行完成(因为JobOperator.start是异步执行),再从监听器的容器中取出对应作业的transientData进行验证:

@Test
void verifyJobTransientData() throws InterruptedException {
    // 启动目标作业
    JobExecutionImpl jobExecution = startJob("your-job.xml", new Properties());
    
    // 等待作业执行完成,循环查询状态直到非运行态
    while (jobExecution.getBatchStatus().isRunning()) {
        Thread.sleep(100);
        jobExecution = (JobExecutionImpl) jobOperator.getJobExecution(jobExecution.getExecutionId());
    }
    
    // 从监听器容器中获取transientData
    Map<String, Object> transientData = TestJobListener.jobTransientData.get(jobExecution.getExecutionId());
    
    // 执行断言验证
    assertNotNull("Transient data should not be null", transientData);
    assertEquals("Expected value for key 'test-key'", "test-value", transientData.get("test-key"));
    
    // 清理测试数据,避免影响其他测试用例
    TestJobListener.jobTransientData.remove(jobExecution.getExecutionId());
}

注意事项

  • 若使用JobOperator.startAndWait方法启动作业,可省略手动等待的逻辑,该方法会阻塞直到作业完成。
  • TestJobListener需要被CDI管理(如添加@ApplicationScoped),否则无法成功注入JobContext。
  • 若需要验证StepContext的transientData,可采用相同思路,实现StepListener并存储对应数据。

内容的提问来源于stack exchange,提问作者Ionut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:10:12