Chapter 17. Java Batch Application Development
Beginning with JBoss EAP 7, JBoss EAP supports Java batch applications as defined by JSR-352. 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.
17.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>
17.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. Although JSL inheritance is not included in the JSR-352 1.0 specification, the JBoss EAP batch-jberet
subsystem implements JSL inheritance based on the JSL Inheritance v1 draft.
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" next="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 byjsl-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>
17.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
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 = '#';