Spring Batch: всегда ищет файлы с MultiResourceItemReader - PullRequest
1 голос
/ 26 марта 2012

Я новичок в Spring Batch. Я унаследовал пакетный процесс, реализованный с помощью Spring Batch. Это хорошо работает, за исключением одной вещи, которую я постараюсь описать.

Я запускаю parseJob и, когда он читает XML, обрабатывает в bean parsingStepReader , Метод read () вызывается всегда.

Каталог * path_to_xml * содержит только один XML, вызывает read () и возвращает проанализированный XML, который обрабатывается ОК. Затем метод read () вызывается снова, возвращает нулевой объект и вызывается снова, возвращает нулевое значение ... и т. Д.

При отладке MultiResourceItemReader read метод пытается прочитать, ничего не читает (все ресурсы уже прочитаны), увеличивает currentResources и возвращает null.

Я прочитал что-то об остановках задания, когда читатель возвращает нулевой объект, но этот метод read возвращает null и читает снова и снова ... Я изменил restartable на false, но не работает.

Задание запускается в Linux в пакетном режиме с помощью org.springframework.batch.core.launch.support.CommandLineJobRunner Из-за этой проблемы .sh, запускающий задание, не завершается, а ресурсы заняты.

Как можно избежать этого или остановить работу, когда входной каталог ресурсов (XML) уже обработан? Любая помощь будет принята с благодарностью. С наилучшими пожеланиями.

Файл Beans и части классов Java прилагаются

<batch:job id="parseJob" restartable="true" incrementer="jobParametersIncrementer">
    <batch:flow parent="parseFlow"/>
    <batch:flow .../>
    <batch:flow .../>
</batch:job>

<batch:flow id="parseFlow">
    <batch:step id="parsingStep">
        <batch:tasklet start-limit="100" allow-start-if-complete="true" transaction-manager="..." task-executor="taskExecutor" throttle-limit="$...">
            <batch:chunk reader="parsingStepReader" writer="..." processor="..." commit-interval="..." skip-limit="10000000">
                <batch:skippable-exception-classes>
                    <batch:include class="java.lang.Exception" />
                </batch:skippable-exception-classes>
            </batch:chunk>
            <batch:listeners>
                <batch:listener ref="iwListener" />
                <batch:listener ref="mySkipListener" />
                <batch:listener ref="myStep1Listener" />
            </batch:listeners>
            <batch:no-rollback-exception-classes>
                <batch:include class="java.lang.Exception" />
            </batch:no-rollback-exception-classes>
        </batch:tasklet>
    </batch:step>
</batch:flow>

<!-- -->

<bean id="bpfReader" class="org.springframework.batch.item.xml.StaxEventItemReader" scope="prototype">
    <property name="fragmentRootElementName" value="..." />
    <property name="unmarshaller" ref="..." />
    <property name="strict" value="false" />
</bean>

<bean id="multiresourceItemReader" class="...SyncMultiResourceItemReader" abstract="true">
    <property name="strict" value="false" />
    <property name="delegate" ref="bpfReader" />
</bean>

<bean id="parsingStepReader" parent="multiresourceItemReader" scope="step">
    <property name="resources" value="<path_to_xml>" />
</bean>

И читатель класс:

public class SyncMultiResourceItemReader<T> extends MultiResourceItemReader<T> {
    . . .

    @Override
    public T read() throws Exception, UnexpectedInputException, ParseException {
        synchronized (this) {
            return super.read();
        }
    }

    . . .
}

ОБНОВЛЕНИЕ : Решение, предложенное @vsingh, работает отлично. Как только элемент ввода выбран, он должен быть удален из ввода. Я не знаю почему, но класс org.springframework.batch.item.file.MultiResourceItemReader не работает, как я ожидал, особенно при ошибке ввода.

Надеюсь, это поможет. С наилучшими пожеланиями

Ответы [ 2 ]

2 голосов
/ 29 марта 2012

Метод read прочитает данные, сохранит их на уровне класса и передаст их методу write. Я дам вам пример того, как мы это сделали

например

@Override
public Long read() throws Exception, UnexpectedInputException,
        ParseException, NonTransientResourceException {
    synchronized (this.myIds) {
        if (!this.myIds.isEmpty()) {
            return this.myIds.remove(0);
        }
        return null;
    }
}

myIds - это список на уровне класса

Этот список заполняется по методу перед шагом

@Override
public void beforeStep(final StepExecution stepExec) {
    this.stepExecution = stepExec;
            // read the ids from service and set at class level  

}
0 голосов
/ 02 июля 2013

Решение, предложенное @vsingh, работает отлично.Как только элемент ввода выбран, он должен быть удален из ввода.Я не знаю почему, но класс org.springframework.batch.item.file.MultiResourceItemReader работает не так, как я ожидал, особенно в случае ошибки ввода.

Надеюсь, это поможет.С наилучшими пожеланиями

...