Chapter 18. Jakarta Batch Application Development JBoss EAP supports Jakarta Batch, defined in the Jakarta EE specification. For information about Jakarta Batch, see Jakarta Batch . The batch-jberet subsystem in JBoss EAP facilitates batch configuration and monitoring. To configure your application to use batch processing on JBoss EAP, you must specify the required dependencies . Additional JBoss EAP features for batch processing include Job Specification Language (JSL) inheritance , and batch property injections . 18.1. Required Batch Dependencies To deploy your batch application to JBoss EAP, some additional dependencies that are required for batch processing need to be declared in your application's pom.xml . An example of these required dependencies is shown below. Most of the dependencies have the scope set to provided , as they are already included in JBoss EAP. Example: pom.xml Batch Dependencies <dependencies> <dependency> <groupId>org.jboss.spec.javax.batch</groupId> <artifactId>jboss-batch-api_1.0_spec</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>javax.enterprise</groupId> <artifactId>cdi-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.spec.javax.annotation</groupId> <artifactId>jboss-annotations-api_1.2_spec</artifactId> <scope>provided</scope> </dependency> <!-- Include your application's other dependencies. --> ... </dependencies> 18.2. Job Specification Language (JSL) Inheritance A feature of the JBoss EAP batch-jberet subsystem is the ability to use Job Specification Language (JSL) inheritance to abstract out some common parts of your job definition. Inherit Step and Flow Within the Same Job XML File Parent elements, for example step and flow, are marked with the attribute abstract="true" to exclude them from direct execution. Child elements contain a parent attribute, which points to the parent element. <job id="inheritance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> <!-- abstract step and flow --> <step id="step0" abstract="true"> <batchlet ref="batchlet0"/> </step> <flow id="flow0" abstract="true"> <step id="flow0.step1" parent="step0"/> </flow> <!-- concrete step and flow --> <step id="step1" parent="step0" ="flow1"/> <flow id="flow1" parent="flow0"/> </job> Inherit a Step from a Different Job XML File Child elements, for example step and job, contain: A jsl-name attribute, which specifies the job XML file name, without the .xml extension, containing the parent element. A parent attribute, which points to the parent element in the job XML file specified by jsl-name . Parent elements are marked with the attribute abstract="true" to exclude them from direct execution. Example: chunk-child.xml <job id="chunk-child" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> <step id="chunk-child-step" parent="chunk-parent-step" jsl-name="chunk-parent"> </step> </job> Example: chunk-parent.xml <job id="chunk-parent" > <step id="chunk-parent-step" abstract="true"> <chunk checkpoint-policy="item" skip-limit="5" retry-limit="5"> <reader ref="R1"></reader> <processor ref="P1"></processor> <writer ref="W1"></writer> <checkpoint-algorithm ref="parent"> <properties> <property name="parent" value="parent"></property> </properties> </checkpoint-algorithm> <skippable-exception-classes> <include class="java.lang.Exception"></include> <exclude class="java.io.IOException"></exclude> </skippable-exception-classes> <retryable-exception-classes> <include class="java.lang.Exception"></include> <exclude class="java.io.IOException"></exclude> </retryable-exception-classes> <no-rollback-exception-classes> <include class="java.lang.Exception"></include> <exclude class="java.io.IOException"></exclude> </no-rollback-exception-classes> </chunk> </step> </job> 18.3. Batch Property Injections A feature of the JBoss EAP batch-jberet subsystem is the ability to have properties defined in the job XML file injected into fields in the batch artifact class. Properties defined in the job XML file can be injected into fields using the @Inject and @BatchProperty annotations. The injection field can be any of the following Java types: java.lang.String java.lang.StringBuilder java.lang.StringBuffer any primitive type, and its wrapper type: boolean , Boolean int , Integer double , Double long , Long char , Character float , Float short , Short byte , Byte java.math.BigInteger java.math.BigDecimal java.net.URL java.net.URI java.io.File java.util.jar.JarFile java.util.Date java.lang.Class java.net.Inet4Address java.net.Inet6Address java.util.List , List<?> , List<String> java.util.Set , Set<?> , Set<String> java.util.Map , Map<?, ?> , Map<String, String> , Map<String, ?> java.util.logging.Logger java.util.regex.Pattern javax.management.ObjectName The following array types are also supported: java.lang.String[] any primitive type, and its wrapper type: boolean[] , Boolean[] int[] , Integer[] double[] , Double[] long[] , Long[] char[] , Character[] float[] , Float[] short[] , Short[] byte[] , Byte[] java.math.BigInteger[] java.math.BigDecimal[] java.net.URL[] java.net.URI[] java.io.File[] java.util.jar.JarFile[] java.util.zip.ZipFile[] java.util.Date[] java.lang.Class[] Shown below are a few examples of using batch property injections: Injecting a Number into a Batchlet Class as Various Types Injecting a Number Sequence into a Batchlet Class as Various Arrays Injecting a Class Property into a Batchlet Class Assigning a Default Value to a Field Annotated for Property Injection Injecting a Number into a Batchlet Class as Various Types Example: Job XML File <batchlet ref="myBatchlet"> <properties> <property name="number" value="10"/> </properties> </batchlet> Example: Artifact Class @Named public class MyBatchlet extends AbstractBatchlet { @Inject @BatchProperty int number; // Field name is the same as batch property name. @Inject @BatchProperty (name = "number") // Use the name attribute to locate the batch property. long asLong; // Inject it as a specific data type. @Inject @BatchProperty (name = "number") Double asDouble; @Inject @BatchProperty (name = "number") private String asString; @Inject @BatchProperty (name = "number") BigInteger asBigInteger; @Inject @BatchProperty (name = "number") BigDecimal asBigDecimal; } Injecting a Number Sequence into a Batchlet Class as Various Arrays Example: Job XML File <batchlet ref="myBatchlet"> <properties> <property name="weekDays" value="1,2,3,4,5,6,7"/> </properties> </batchlet> Example: Artifact Class @Named public class MyBatchlet extends AbstractBatchlet { @Inject @BatchProperty int[] weekDays; // Array name is the same as batch property name. @Inject @BatchProperty (name = "weekDays") // Use the name attribute to locate the batch property. Integer[] asIntegers; // Inject it as a specific array type. @Inject @BatchProperty (name = "weekDays") String[] asStrings; @Inject @BatchProperty (name = "weekDays") byte[] asBytes; @Inject @BatchProperty (name = "weekDays") BigInteger[] asBigIntegers; @Inject @BatchProperty (name = "weekDays") BigDecimal[] asBigDecimals; @Inject @BatchProperty (name = "weekDays") List asList; @Inject @BatchProperty (name = "weekDays") List<String> asListString; @Inject @BatchProperty (name = "weekDays") Set asSet; @Inject @BatchProperty (name = "weekDays") Set<String> asSetString; } Injecting a Class Property into a Batchlet Class Example: Job XML File <batchlet ref="myBatchlet"> <properties> <property name="myClass" value="org.jberet.support.io.Person"/> </properties> </batchlet> Example: Artifact Class @Named public class MyBatchlet extends AbstractBatchlet { @Inject @BatchProperty private Class myClass; } Assigning a Default Value to a Field Annotated for Property Injection You can assign a default value to a field in an artifact Java class in the case where the target batch property is not defined in the job XML file. If the target property is resolved to a valid value, it is injected into that field; otherwise, no value is injected and the default field value is used. Example: Artifact Class /** Comment character. If commentChar batch property is not specified in job XML file, use the default value '#'. */ @Inject @BatchProperty private char commentChar = '#';

Commands:
<dependencies> <dependency> <groupId>org.jboss.spec.javax.batch</groupId> <artifactId>jboss-batch-api_1.0_spec</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>javax.enterprise</groupId> <artifactId>cdi-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.spec.javax.annotation</groupId> <artifactId>jboss-annotations-api_1.2_spec</artifactId> <scope>provided</scope> </dependency> <!-- Include your application's other dependencies. --> </dependencies>
<job id="inheritance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> <!-- abstract step and flow --> <step id="step0" abstract="true"> <batchlet ref="batchlet0"/> </step> <flow id="flow0" abstract="true"> <step id="flow0.step1" parent="step0"/> </flow> <!-- concrete step and flow --> <step id="step1" parent="step0" next="flow1"/> <flow id="flow1" parent="flow0"/> </job>
<job id="chunk-child" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> <step id="chunk-child-step" parent="chunk-parent-step" jsl-name="chunk-parent"> </step> </job>
<job id="chunk-parent" > <step id="chunk-parent-step" abstract="true"> <chunk checkpoint-policy="item" skip-limit="5" retry-limit="5"> <reader ref="R1"></reader> <processor ref="P1"></processor> <writer ref="W1"></writer> <checkpoint-algorithm ref="parent"> <properties> <property name="parent" value="parent"></property> </properties> </checkpoint-algorithm> <skippable-exception-classes> <include class="java.lang.Exception"></include> <exclude class="java.io.IOException"></exclude> </skippable-exception-classes> <retryable-exception-classes> <include class="java.lang.Exception"></include> <exclude class="java.io.IOException"></exclude> </retryable-exception-classes> <no-rollback-exception-classes> <include class="java.lang.Exception"></include> <exclude class="java.io.IOException"></exclude> </no-rollback-exception-classes> </chunk> </step> </job>
<batchlet ref="myBatchlet"> <properties> <property name="number" value="10"/> </properties> </batchlet>
@Named public class MyBatchlet extends AbstractBatchlet { @Inject @BatchProperty int number; // Field name is the same as batch property name. @Inject @BatchProperty (name = "number") // Use the name attribute to locate the batch property. long asLong; // Inject it as a specific data type. @Inject @BatchProperty (name = "number") Double asDouble; @Inject @BatchProperty (name = "number") private String asString; @Inject @BatchProperty (name = "number") BigInteger asBigInteger; @Inject @BatchProperty (name = "number") BigDecimal asBigDecimal; }
<batchlet ref="myBatchlet"> <properties> <property name="weekDays" value="1,2,3,4,5,6,7"/> </properties> </batchlet>
@Named public class MyBatchlet extends AbstractBatchlet { @Inject @BatchProperty int[] weekDays; // Array name is the same as batch property name. @Inject @BatchProperty (name = "weekDays") // Use the name attribute to locate the batch property. Integer[] asIntegers; // Inject it as a specific array type. @Inject @BatchProperty (name = "weekDays") String[] asStrings; @Inject @BatchProperty (name = "weekDays") byte[] asBytes; @Inject @BatchProperty (name = "weekDays") BigInteger[] asBigIntegers; @Inject @BatchProperty (name = "weekDays") BigDecimal[] asBigDecimals; @Inject @BatchProperty (name = "weekDays") List asList; @Inject @BatchProperty (name = "weekDays") List<String> asListString; @Inject @BatchProperty (name = "weekDays") Set asSet; @Inject @BatchProperty (name = "weekDays") Set<String> asSetString; }
<batchlet ref="myBatchlet"> <properties> <property name="myClass" value="org.jberet.support.io.Person"/> </properties> </batchlet>
@Named public class MyBatchlet extends AbstractBatchlet { @Inject @BatchProperty private Class myClass; }
/** Comment character. If commentChar batch property is not specified in job XML file, use the default value '#'. */ @Inject @BatchProperty private char commentChar = '#';