3 Replies Latest reply on Feb 15, 2018 11:16 AM by cfang

    ItemProcessor skip record

    richardmoore

      Is there a way to throw an exception in the ItemProcessor and have it trigger the SkipReadListener? I want to write out unreadable records and records that cannot be reformatted written to the same error file.

       

      <listeners>

      &step-listeners;

      <listener ref="com.awginc.scm.tpa.offinvoice.util.InputRecordSkipListener" />

      </listeners>

       

      <properties>

      <property name="resource" value="#{jobProperties['inputErrorResource']}" />

      </properties>

       

      <chunk item-count="3000">

      <skippable-exception-classes>

      <include class="org.beanio.BeanReaderException" />

      </skippable-exception-classes>

       

      <reader ref="beanIOItemReader">

      <properties>

      <property name="resource" value="#{jobProperties['inputResource']}" />

      <property name="streamName" value="#{jobProperties['inputStreamName']}" />

      <property name="streamMapping" value="#{jobProperties['inputStreamMapping']}" />

      </properties>

      </reader>

       

      <processor ref="com.awginc.scm.tpa.offinvoice.InputValidationProcessor" />

       

      <writer ref="beanIOItemWriter">

      <properties>

      <property name="resource" value="#{jobProperties['reformattedResource']}" />

      <property name="streamName" value="#{jobProperties['reformattedStreamName']}" />

      <property name="streamMapping" value="#{jobProperties['reformattedStreamMapping']}" />

      </properties>

      </writer>

      </chunk>

        • 1. Re: ItemProcessor skip record
          cfang

          No, since item processor works after item reader.  However, such an exception from item processor will trigger SkipProcessListener.

           

          If your purpose is for better code organization, you can move the error-recording to a separate class that can be shared between reading, processing & writing parts.  That class can be a singleton, or bean class with appropriate CDI scope (e.g., StepScoped) to ensure the same bean instance is used by all parties.

          • 2. Re: ItemProcessor skip record
            richardmoore

            Do you happen to have an example of this I could reference?

            • 3. Re: ItemProcessor skip record
              cfang

              import javax.inject.Named;

              import org.jberet.cdi.StepScoped;

               

              @Named

              @StepScoped

              //@PartitionScoped

              //@javax.inject.Singleton

              public class ErrorRecordingBean {

                 FileWriter fw = ...

               

                   public void addErrorRecord(String error) {...}

               

                  public void writeErrorRecord(String error) {...}

                 

              }

               

              In your read listener or item process listener, inject the above ErrorRecordingBean:

               

              @Inject

              private ErrorRecordingBean errorRecorder;

               

              With StepScoped, If your step is partitioned, then multiple partitions of the same step will share the same bean instance, and this bean class should be implemented in a thread-safe manner.  Even more so with Singleton scope, where all producers of error records will share the same instance.

               

              This is based on CDI, so make sure your batch artifact ref in job .xml is declared with cdi bean name (not the fully qualified class name).