Java пакет: jobContext transientUserData не прошел через шаги - PullRequest
1 голос
/ 19 февраля 2020

Я использую реализацию JBeret спецификаций jsr-352.

Вкратце, это моя конфигурация работы:

<job id="expired-customer-cancellation" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
     version="1.0" jsl-name="job-parent" parent="job-parent">
    <step id="step1" next="step2">
        <chunk item-count="#{jobParameters['chunksize']}?:3">
            <reader ref="eccReader">
            </reader>
            <writer ref="eccWriter" />
        </chunk>
        <partition>
            <mapper ref="eccMapper">
                <properties>
                    <property name="threads" value="#{jobParameters['threads']}?:3"/>
                    <property name="records" value="#{jobParameters['records']}?:30"/>
                </properties>
            </mapper>
        </partition>
    </step>
    <step id="step2">
        <batchlet ref="eccMailBatchlet" />
    </step>
</job>

Класс Itemwriter делает что-то вроде этого:

@Named
public class EccWriter extends AbstractItemWriter {

    @Inject
    Logger logger;

    @Inject
    JobContext jobContext;

    @Override
    public void writeItems(List<Object> list) throws Exception {
        @SuppressWarnings("unchecked")
        ArrayList<String> processed = Optional.ofNullable(jobContext.getTransientUserData()).map(ArrayList.class::cast).orElse(new ArrayList<String>());
        list.stream().map(UserLogin.class::cast).forEach(input -> {

            if (someConditions) {

                processed.add(input.getUserId());

            }
        });

        jobContext.setTransientUserData(processed); // update job transient data with processed list
    }
}

Теперь я ожидаю получить обновленный список при вызове jobContext.getTransientUserData () для step2 , вместо этого я получаю только значение null .

Кроме того, каждый раздел имеет свой собственный jobContext.transientUserData, поэтому он всегда будет начинаться со значения null в начале раздела.

Я думаю, что jobContext сам по себе может ввести в заблуждение распространенные ошибки из-за его имя.

Каков естественный способ передачи данных через всю работу?

1 Ответ

1 голос
/ 19 февраля 2020

Это пробел в текущем API, и поведение "локального потока" может быть удивительным, я согласен.

Один из методов, который вы можете использовать, - использовать вместо этого постоянные пользовательские данные.

Например, с шага 1:

StepExecution.setPersistentUserData(processed);

Затем с шага 2:

@Inject 
JobContext ctx;

List<StepExecution> stepExecs = BatchRuntime.getJobOperator().getStepExecutions(ctx.getInstanceId());

// ... not shown here, but sort through stepExecs and find the one from step1.
StepExecution step2Exec = ... ;  

Serializable userData = step2Exec.getPersistentUserData()

Это было отмечено ранее как область для улучшений, и ее следует учитывать для будущих улучшений для Jakarta Batch (новый источник спецификации).

...