JSR 352. Почему исключение, включенное в <skippable-exception-classes>, останавливает работу

Я пытаюсь создать простое пакетное приложение, используя JSR 352 с Websphere Liberty Profile 17.0.0.2. Кажется, что все работает нормально до обработки исключений. Я предполагаю, что исключения, создаваемые приложением, указанным в узле 'skippable-exception-classes' в файле job.xml, будут несколько игнорироваться / пропускаться и позволят заданию перейти к следующим элементам / шагам.

Проблема, с которой я сталкиваюсь, возникает всякий раз, когда исключение выдается из внедренного компонента (через @Inject) при вызове одного из его методов. Задание просто останавливается на текущем элементе / шаге, где было сгенерировано исключение.

Странно то, что всякий раз, когда я вручную / явно выкидываю одно и то же исключение, скажем, RecordNotFoundException, работа продолжается, что я и ожидал. Проблема возникает только в том случае, если исключение вызвано из введенного компонента. Я добавил @ApplicationException в класс исключений, чтобы исключить / развернуть исключение.

Я что-то пропустил? Это ошибка в Websphere Liberty?

РЕДАКТИРОВАТЬ: Добавлен упрощенный код

SampleSharedLibrary - зависимость от другого проекта /jar

package sample;

import javax.ejb.ApplicationException;
import javax.ejb.Stateless;

@Stateless
public class SampleSharedLibrary {

    public String someMethod(String object) {
        String result = null;

        if(object != null) {
            result = "OK";
        } else {
            throw new MyException();
        }

        return result;
    }

    @ApplicationException(rollback = true)
    public static class MyException extends RuntimeException {
        public MyException() {}
    }
}

Приложение BatchExample

SampleWriter import sample.SampleSharedLibrary;

import javax.batch.api.chunk.AbstractItemWriter;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.List;

@Dependent
@Named("SampleWriter")
public class SampleWriter extends AbstractItemWriter{

    @Inject
    SampleSharedLibrary sharedLibrary;

    public void writeItems(List<Object> list) throws Exception {
        for(Object item : list) {
            sharedLibrary.someMethod(item.toString());
        }
    }
}

SampleReader

import javax.batch.api.chunk.AbstractItemReader;
import javax.enterprise.context.Dependent;
import javax.inject.Named;
import java.io.Serializable;

@Dependent
@Named("SampleReader")
public class SampleReader extends AbstractItemReader {

    String[] sample;
    int index;
    @Override
    public void open(Serializable checkpoint) throws Exception {
        sample = new String[]{"S1", null, "S3"};
        index = 0;
    }

    public Object readItem() throws Exception {
        Object item = null;

        if(index < sample.length) {
            item = sample[index];
            index++;
        }

        return item;
    }
}

job.xml

<job id="myJob" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
    <step id="myStep" >
        <chunk item-count="1" skip-limit="50">
            <reader ref="SampleReader"/>
            <writer ref="SampleWriter"/>
            <skippable-exception-classes>
                <include class="java.lang.Exception"/>
                <include class="sample.SampleSharedLibrary$MyException"/>
            </skippable-exception-classes>
        </chunk>
    </step>
</job>

Что касается server.xml, добавлена ​​не слишком большая конфигурация, но я включил следующие функции: cdi-1.2, ejbLite-3.2, jaxrs-2.0, jpa-2.0, jsf-2.2, managedBeans-1.0, servlet-3.1, localConnector-1.0, пакет-1.0 и json-1.0

При обнаружении ошибки из реального приложения, я получаю журналы, как показано ниже (пришлось изменить некоторые значения на звездочки):

[02-11-17 21:38:12:323 CST] 000000d1 com.ibm.ws.logging.internal.impl.IncidentImpl                I FFDC1015I: An FFDC Incident has been created: "*******.**********.*******.batchflows.service.writer.ErrorWhileUpdating: *******.**********.*******.infrastructure.*****.commands.OurCommand$RecordNotFound: recordId=31AA69FAE017D21F com.ibm.jbatch.container.controller.impl.ChunkStepControllerImpl 485" at ffdc_17.11.02_21.38.12.0.log
[02-11-17 21:38:12:352 CST] 000000d1 com.ibm.ws.logging.internal.impl.IncidentImpl                I FFDC1015I: An FFDC Incident has been created: "com.ibm.jbatch.container.exception.BatchContainerRuntimeException: *******.**********.*******.batchflows.service.writer.ErrorWhileUpdating: *******.**********.*******.infrastructure.*****.commands.OurCommand$RecordNotFound: recordId=31AA69FAE017D21F com.ibm.jbatch.container.controller.impl.ChunkStepControllerImpl 1041" at ffdc_17.11.02_21.38.12.1.log
[02-11-17 21:38:12:363 CST] 000000d1 com.ibm.ws.logging.internal.impl.IncidentImpl                I FFDC1015I: An FFDC Incident has been created: "javax.transaction.RollbackException com.ibm.jbatch.container.transaction.impl.JTAUserTransactionAdapter 107" at ffdc_17.11.02_21.38.12.2.log
[02-11-17 21:38:12:385 CST] 000000d1 com.ibm.ws.logging.internal.impl.IncidentImpl                I FFDC1015I: An FFDC Incident has been created: "com.ibm.jbatch.container.exception.TransactionManagementException: javax.transaction.RollbackException com.ibm.jbatch.container.controller.impl.ChunkStepControllerImpl 680" at ffdc_17.11.02_21.38.12.3.log

1 ответ

Решение

Контейнер EJB все еще может откатить пакетную транзакцию, даже если пакетный контейнер пропускает указанное исключение

Конфигурирование XML вашего задания для пропуска заданного исключения только предотвратит пометку контейнером пакета транзакции чанка для отката. Это не помешает кому-то еще пометить транзакцию для отката.

Это означает, что контейнер EJB может сам откатить транзакцию. Так что в вашем случае вам нужно будет использовать:

@ApplicationException(rollback = false)
public static class MyException extends RuntimeException {

или, в стиле предварительной аннотации, вам нужно будет использовать проверенное исключение, а не непроверенное исключение, чтобы предотвратить откат транзакции контейнером EJB.

Другие вопросы по тегам