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 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>

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 = '#';