1. License
Specification: Jakarta Batch Version: {revnumber} Status: Final Release Release: {revdate}
Copyright (c) 2019 Eclipse Foundation.
1.1. Eclipse Foundation Specification License
By using and/or copying this document, or the Eclipse Foundation document from which this statement is linked, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions:
Permission to copy, and distribute the contents of this document, or the Eclipse Foundation document from which this statement is linked, in any medium for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the document, or portions thereof, that you use:
-
link or URL to the original Eclipse Foundation document.
-
All existing copyright notices, or if one does not exist, a notice (hypertext is preferred, but a textual representation is permitted) of the form: "Copyright (c) [$date-of-document] Eclipse Foundation, Inc. [url to this license]"
Inclusion of the full text of this NOTICE must be provided. We request that authorship attribution be provided in any software, documents, or other items or products that you create pursuant to the implementation of the contents of this document, or any portion thereof.
No right to create modifications or derivatives of Eclipse Foundation documents is granted pursuant to this license, except anyone may prepare and distribute derivative works and portions of this document in software that implements the specification, in supporting materials accompanying such software, and in documentation of such software, PROVIDED that all such works include the notice below. HOWEVER, the publication of derivative works of this document for use as a technical specification is expressly prohibited.
The notice is:
"Copyright (c) 2018 Eclipse Foundation. This software or document includes material copied from or derived from [title and URI of the Eclipse Foundation specification document]."
1.1.1.
THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF.
The name and trademarks of the copyright holders or the Eclipse Foundation may NOT be used in advertising or publicity pertaining to this document or its contents without specific, written prior permission. Title to copyright in this document will at all times remain with copyright holders.
2. Acknowledgements
A number of individuals deserve special recognition for their contributions to forming this specification:
-
Kevin Conner
-
Tim Fanelli
-
Cheng Fang
-
Mahesh Kannan
-
Scott Kurz
-
Wayne Lund
-
Simon Martinelli
-
Michael Minella
-
Kaushik Mukherjee
-
Joe Pullen
3. Foreword
This specification describes the job specification language, Java programming model, and runtime environment for batch applications for the Java platform. It is designed for use on both the Java SE and Java EE platforms. Additionally, it is designed to work with dependency injection (DI) containers without prescribing a particular DI implementation.
4. Table of Contents
- 1. License
- 2. Acknowledgements
- 3. Foreword
- 4. Table of Contents
- 5. Introduction to JSR 352
- 6. Applicability of Specification
- 7. Domain Language of Batch
- 8. Job Specification Language
- 8.1. Job
- 8.2. Step
- 8.2.1. Chunk
- 8.2.2. Batchlet
- 8.2.3. Step Level Properties
- 8.2.4. Step Level Listeners
- 8.2.5. Step Sequence
- 8.2.6. Step Partitioning
- 8.2.7. Step Exception Handling
- 8.3. Flow
- 8.4. Split
- 8.5. Decision
- 8.6. Transition Elements
- 8.7. Batch and Exit Status
- 8.8. Job XML Substitution
- 8.8.1. Substitution Processing Rules
- <IP_ADDRESS>. jobParameters Substitution Operator
- <IP_ADDRESS>. jobProperties Substitution Operator
- <IP_ADDRESS>. systemProperties Substitution Operator
- <IP_ADDRESS>. partitionPlan Substitution Operator
- <IP_ADDRESS>. Substitution Expression Default
- <IP_ADDRESS>. Property Resolution Rule
- <IP_ADDRESS>. Undefined Target Name Rule
- <IP_ADDRESS>. Job Restart Rule
- 8.8.2. Examples
- 8.8.1. Substitution Processing Rules
- 8.9. Transitioning Rules
- 9. Batch Programming Model
- 10. Batch Runtime Specification
- 10.1. Batch Properties Reserved Namespace
- 10.2. Job Metrics
- 10.3. Job Runtime Identifiers
- 10.4. JobOperator
- 10.5. Batch Artifact Loading
- 10.6. Job XML Loading
- 10.7. Application Packaging Model
- 10.8. Restart Processing
- 10.9. Supporting Classes
- 11. Job Runtime Lifecycle
- 11.1. Batch Artifact Lifecycle
- 11.2. Job Repository Artifact Lifecycle
- 11.3. Job Processsing
- 11.4. Regular Batchlet Processsing
- 11.5. Partitioned Batchlet Processsing
- 11.6. Regular Chunk Processing
- 11.7. Partitioned Chunk Processing
- 11.8. Chunk with Listeners (except RetryListener)
- 11.9. Chunk with RetryListener
- 11.10. Chunk with Custom Checkpoint Processing
- 11.11. Split Processing
- 11.12. Flow Processing
- 11.13. Stop Processing
- 12. Batch XML XSD
- 13. Job Specification Language
- 14. Credits
- 15. Change Log
5. Introduction to JSR 352
Batch processing is a pervasive workload pattern, expressed by a distinct application organization and execution model. It is found across virtually every industry, applied to such tasks as statement generation, bank postings, risk evaluation, credit score calculation, inventory management, portfolio optimization, and on and on. Nearly any bulk processing task from any business sector is a candidate for batch processing.
Batch processing is typified by bulk-oriented, non-interactive, background execution. Frequently long-running, it may be data or computationally intensive, execute sequentially or in parallel, and may be initiated through various invocation models, including ad hoc, scheduled, and on-demand.
Batch applications have common requirements, including logging, checkpointing, and parallelization. Batch workloads have common requirements, especially operational control, which allow for initiation of, and interaction with, batch instances; such interactions include stop and restart.
6. Applicability of Specification
This specification applies to Java SE and Java EE environments. It requires Java 6 or higher.
7. Domain Language of Batch
To any experienced batch architect, the overall concepts of batch processing used by JSR 352 should be familiar and comfortable. There are "Jobs" and "Steps" and developer supplied processing units called ItemReaders and ItemWriters. However, because of the JSR 352 operations, callbacks, and idioms, there are opportunities for the following:
-
significant improvement in adherence to a clear separation of concerns
-
clearly delineated architectural layers and services provided as interfaces
-
significantly enhanced extensibility
The diagram below is a simplified version of the batch reference architecture that has been used for decades. It provides an overview of the components that make up the domain language of batch processing. This architecture framework is a blueprint that has been proven through decades of implementations on the last several generations of platforms (COBOL/Mainframe, C/Unix, and now Java/anywhere). JCL and COBOL developers are likely to be as comfortable with the concepts as C, C# and Java developers. JSR 352 specifies the layers, components and technical services commonly found in robust, maintainable systems used to address the creation of simple to complex batch applications.
The diagram above highlights the key concepts that make up the domain language of batch. A Job has one to many steps, which has no more than one ItemReader, ItemProcessor, and ItemWriter. A job needs to be launched (JobOperator), and meta data about the currently running process needs to be stored (JobRepository).
7.1. Job
A Job is an entity that encapsulates an entire batch process. A Job will be wired together via a Job Specification Language. However, Job is just the top of an overall hierarchy:
With JSR 352, a Job is simply a container for Steps. It combines multiple steps that belong logically together in a flow and allows for configuration of properties global to all steps, such as restartability. The job configuration contains:
-
The simple name of the job
-
Definition and ordering of Steps
-
Whether or not the job is restartable
7.1.1. JobInstance
A JobInstance refers to the concept of a logical job run. Let’s consider a batch job that should be run once at the end of the day, such as the 'EndOfDay' job from the diagram above. There is one 'EndOfDay' Job, but each individual run of the Job must be tracked separately. In the case of this job, there will be one logical JobInstance per day. For example, there will be a January 1st run, and a January 2nd run. If the January 1st run fails the first time and is run again the next day, it is still the January 1st run. Usually this corresponds with the data it is processing as well, meaning the January 1st run processes data for January 1st, etc. Therefore, each JobInstance can have multiple executions (JobExecution is discussed in more detail below); one or many JobInstances corresponding to a particular Job can be running at a given time.
The definition of a JobInstance has absolutely no bearing on the data that will be loaded. It is entirely up to the ItemReader implementation used to determine how data will be loaded. For example, in the EndOfDay scenario, there may be a column on the data that indicates the 'effective date' or 'schedule date' to which the data belongs. So, the January 1st run would only load data from the 1st, and the January 2nd run would only use data from the 2nd. Because this determination will likely be a business decision, it is left up to the ItemReader to decide. What using the same JobInstance will determine, however, is whether or not the 'state' from previous executions will be available to the new run. Using a new JobInstance will mean 'start from the beginning' and using an existing instance will generally mean 'start from where you left off'.
7.1.2. JobParameters
Job parameters can be specified each time a job is started or restarted. Job parameters are keyword/value string pairs. The JobOperator start and restart operations support the specification of job parameters. See section 10.4 for further details on JobOperator.
7.2. Step
A Step is a domain object that encapsulates an independent, sequential phase of a batch job. Therefore, every Job is composed entirely of one or more steps. A Step contains all of the information necessary to define and control the actual batch processing. This is a necessarily vague description because the contents of any given Step are at the discretion of the developer writing it. A Step can be as simple or complex as the developer desires. A simple Step might load data from a file into the database, requiring little or no code, depending upon the implementations used. A more complex Step may have complicated business rules that are applied as part of the processing. As with Job, a Step has an individual StepExecution that corresponds with a unique JobExecution:
7.2.1. StepExecution
A StepExecution represents a single attempt to execute a Step. A new StepExecution will be created each time a Step is run, similar to JobExecution. However, if a step fails to execute because the step before it fails, there will be no execution persisted for it. A StepExecution will only be created when its Step is actually started.
7.3. JobOperator
JobOperator provides an interface to manage all aspects of job processing, including operational commands, such as start, restart, and stop, as well as job repository related commands, such as retrieval of job and step executions. See section 10.4 for more details about JobOperator.
7.4. Job Repository
A job repository holds information about jobs currently running and jobs that have run in the past. The JobOperator interface provides access to this repository. The repository contains job instances, job executions, and step executions. For further information on this content, see sections 10.9.8, 10.9.9, 10.9.10, respectively.
Note the implementation of the job repository is outside the scope of this specification.
7.5. ItemReader
ItemReader is an abstraction that represents the retrieval of input for a Step, one item at a time. An ItemReader provides an indicator when it has exhausted the items it can supply. See section <IP_ADDRESS> for more details about ItemReaders.
7.6. ItemWriter
ItemWriter is an abstraction that represents the output of a Step, one batch or chunk of items at a time. Generally, an item writer has no knowledge of the input it will receive next, only the item that was passed in its current invocation. See section <IP_ADDRESS> for more details about ItemWriters.
7.7. ItemProcessor
ItemProcessor is an abstraction that represents the business processing of an item. While the ItemReader reads one item, and the ItemWriter writes them, the ItemProcessor provides access to transform or apply other business processing. See section <IP_ADDRESS> for more details about ItemProcessors.
7.8. Chunk-oriented Processing
JSR 352 specifies a 'Chunk Oriented' processing style as its primary pattern. Chunk oriented processing refers to reading the data one item at a time, and creating 'chunks' that will be written out, within a transaction boundary. One item is read in from an ItemReader, handed to an ItemProcessor, and aggregated. Once the number of items read equals the commit interval, the entire chunk is written out via the ItemWriter, and then the transaction is committed.
7.9. Batch Checkpoints
For data intensive batch applications - particularly those that may run for long periods of time - checkpoint/restart is a common design requirement. Checkpoints allow a step execution to periodically bookmark its current progress to enable restart from the last point of consistency, following a planned or unplanned interruption.
Checkpoints work naturally with chunk-oriented processing. The end of processing for each chunk is a natural point for taking a checkpoint.
JSR 352 specifies runtime support for checkpoint/restart in a generic way that can be exploited by any chunk-oriented batch step that has this requirement.
Since progress during a step execution is really a function of the current position of the input/output data, natural placement of function suggests the knowledge for saving/restoring current position is a reader/writer responsibility.
Since managing step execution is a runtime responsibility, the batch runtime must necessarily understand step execution lifecycle, including initial start, execution end states, and restart.
Since checkpoint frequency has a direct effect on lock hold times, for lockable resources, tuning checkpoint interval size can have a direct bearing on overall system throughput.
8. Job Specification Language
Job Specification Language (JSL) specifies a job, its steps, and directs their execution. The JSL for JSR 352 is implemented with XML and will be henceforth referred to as "Job XML".
8.1. Job
The 'job' element identifies a job.
Syntax:
<job id="{name}" restartable="{true|false}">
Where:
id |
Specifies the logical name of the job and is used for identification purposes. It must be a valid XML string value. This is a required attribute. |
restartable |
Specifies whether or not this job is restartable . It must specify true or false. This is an optional attribute. The default is true. |
8.1.1. Job Level Listeners
Job level listeners may be configured to a job in order to intercept job execution. The listener element may be specified as child element of the job element for this purpose. Job listener is the only listener type that may be specified as a job level listener.
Multiple listeners may be configured on a job. However, there is no guarantee of the order in which they are invoked.
Syntax:
<listeners>
<listener ref="{name}">
...
</listeners>
Where:
ref |
Specifies the name of a batch artifact. |
8.1.2. Job Level Exception Handling
Any unhandled exception thrown by a job-level listener causes the job to terminate with a batch status of FAILED. In this context, "unhandled" simply means an exception thrown by the listener back to the runtime implementation.
8.1.3. Job Level Properties
The 'properties' element may be specified as a child element of the job element. It is used to expose properties to any batch artifact belonging to the job and also to the batch runtime. Any number of properties may be specified. Job level properties are available through the JobContext runtime object. See section 9.4 for further information about Job Context.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
name |
Specifies a unique property name within the current scope. It must be a valid XML string value. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
8.2. Step
The 'step' element identifies a job step and its characteristics. Step is a child element of job. A job may contain any number of steps. Each step may be either a chunk type step or batchlet type step. See section 8.2.1 for information on chunk type steps and section 8.2.2 for information on batchlet type steps.
Syntax:
<step id="{name}"
start-limit="{integer}"
allow-start-if-complete ="{true|false}"
next="{flow-id|step-id|split-id|decision-id}">
Where:
id |
Specifies the logical name of the step and is used for identification purposes. It must be a valid XML string value. This is a required attribute. |
start-limit |
Specifies the number of times this step may be started or restarted. It must be a valid XML integer value. This is an optional attribute. The default is 0, which means no limit. If the limit is exceeded, the job is placed in the FAILED state. |
allow-start-if-complete |
Specifies whether this step is allowed to start during job restart, even if the step completed in a previous execution. It must be true or false. A value of true means the step is allowed to restart. This is an optional attribute. The default is false. |
next |
Specifies the next step, flow, split, or decision to run after this step is complete. It must be a valid XML string value. This is an optional attribute. The default is this step is the last step in the job or flow. Note: next attributes cannot be specified such that a loop occurs among steps. |
8.2.1. Chunk
The 'chunk' element identifies a chunk type step. It is a child element of the step element. A chunk type step is periodically checkpointed by the batch runtime according to a configured checkpoint policy. Items processed between checkpoints are referred to as a "chunk". A single call is made to the ItemWriter per chunk. Each chunk is processed in a separate transaction. See section 9.7 for more details on transactionality. A chunk that is not complete is restartable from its last checkpoint. A chunk that is complete and belongs to a step configured with allow-start-if-complete=true runs from the beginning when restarted.
Syntax:
<chunk checkpoint-policy="\{item|custom}"
item-count="{value}"
time-limit="{value}"
skip-limit="{value}"
retry-limit="{value}" />
Where:
checkpoint-policy |
Specifies the checkpoint policy that governs commit behavior for this chunk. Valid values are: "item" or "custom". The "item" policy means the chunk is checkpointed after a specified number of items are processed. The "custom" policy means the chunk is checkpointed according to a checkpoint algorithm implementation. Specifying "custom" requires that the checkpoint-algorithm element is also specified. See section <IP_ADDRESS> for checkpoint-algorithm. It is an optional attribute. The default policy is "item". |
item-count |
Specifies the number of items to process per chunk when using the item checkpoint policy. It must be valid XML integer. It is an optional attribute. The default is 10. The item-count attribute is ignored for "custom" checkpoint policy. |
time-limit |
Specifies the amount of time in seconds before taking a checkpoint for the item checkpoint policy. It must be valid XML integer. It is an optional attribute. The default is 0, which means no limit. When a value greater than zero is specified, a checkpoint is taken when time-limit is reached or item-count items have been processed, whichever comes first. The time-limit attribute is ignored for "custom" checkpoint policy. |
skip-limit |
Specifies the number of exceptions a step will skip if any configured skippable exceptions are thrown by chunk processing. It must be a valid XML integer value. It is an optional attribute. The default is no limit. |
retry-limit |
Specifies the number of times a step will retry if any configured retryable exceptions are thrown by chunk processing. It must be a valid XML integer value. It is an optional attribute. The default is no limit. |
<IP_ADDRESS>. Reader
The 'reader' element specifies the item reader for a chunk step. It is a child element of the 'chunk' element. A chunk step must have one and only one item reader.
Syntax:
<reader ref="{name}"/>
Where:
ref |
Specifies the name of a batch artifact. |
<IP_ADDRESS>.1. Reader Properties
The 'properties' element may be specified as a child element of the reader element. It is used to pass property values to a item reader. Any number of properties may be specified.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
name |
Specifies a unique property name within the current scope. It must be a valid XML string value. If it matches a named property in the associated batch artifact, its value is assigned to that property. If not, it is ignored. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
<IP_ADDRESS>. Processor
The 'processor' element specifies the item processor for a chunk step. It is a child element of the 'chunk' element. The processor element is optional on a chunk step. Only a single processor element may be specified.
Syntax:
<processor ref="{name}"/>
Where:
ref |
Specifies the name of a batch artifact. |
<IP_ADDRESS>.1. Processor Properties
The 'properties' element may be specified as a child element of the processor element. It is used to pass property values to a item processor. Any number of properties may be specified.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
name |
Specifies a unique property name within the current scope. It must be a valid XML string value. If it matches a named property in the associated batch artifact, its value is assigned to that property. If not, it is ignored. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
<IP_ADDRESS>. Writer
The 'writer' element specifies the item writer for a chunk step. It is a child element of the 'chunk' element. A chunk type step must have one and only one item writer.
Syntax:
<writer ref="{name}"/>
Where:
ref |
Specifies the name of a batch artifact. |
<IP_ADDRESS>.1. Writer Properties
The 'properties' element may be specified as a child element of the writer element. It is used to pass property values to a item writer. Any number of properties may be specified.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
name |
Specifies a unique property name within the current scope. It must be a valid XML string value. If it matches a named property in the associated batch artifact, its value is assigned to that property. If not, it is ignored. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
<IP_ADDRESS>. Chunk Exception Handling
By default, when any batch artifact that is part of a chunk type step throws an exception to the Batch Runtime, the job execution ends with a batch status of FAILED. The default behavior can be overridden for a reader, processor, or writer artifact by configuring exceptions to skip or to retry. The default behavior can be overridden for the entire step by configuring a transition element that matches the step’s exit status.
<IP_ADDRESS>.1. Skipping Exceptions
The skippable-exception-classes element specifies a set of exceptions that chunk processing will skip. This element is a child element of the chunk element. It applies to exceptions thrown from the reader, processor, and writer batch artifacts of a chunk type step. It also applies to exceptions thrown during checkpoint commit processing. A failed commit will be treated the same as a failed write. The total number of skips is set by the skip-limit attribute on the chunk element. See section 8.2.1 for details on the chunk element.
A given exception will be skipped if it "matches" an include child element of the skippable-exception-classes element, though this might be negated (and the exception not skipped) if it also "matches" an exclude child element of skippable-exception-classes.
The behavior is determined by the "nearest superclass" in the class hierarchy.
To elaborate, in this context, "matches" means the following: For an include (or exclude) element C with @class attribute value T, an exception E "matches" C when either E is of type T or E’s type is a subclass of T.
When an exception E "matches" both one or more include and one or more exclude elements, then there will be one type T1 among all the matching include/exclude elements such that all other distinct matching element types are superclasses of T1 (because of Java’s single inheritance). If T1 only occurs in a matching include element then include (skip) this exception. If T1 appears in a matching exclude element (even if it also appears in a matching include element), then exclude (don’t skip) this exception.
Optional Skip Listener batch artifacts can be configured to the step. A Skip Listener receives control after a skippable exception is thrown by the reader, processor, or writer. See section 9.2.7 for details on the Skip Listener batch interfaces.
Syntax:
<skippable-exception-classes>
<include class="{class name}"/>
<exclude class="{class name}"/>
</skippable-exception-classes>
Where:
include class |
Specifies the class name of an exception or exception superclass to skip. It must be a fully qualified class name. Multiple instances of the include element may be specified. The include child element is optional. However, when specified, the class attribute is required. |
exclude class |
Specifies a class name of an exception or exception superclass to not skip. 'Exclude class' reduces the number of exceptions eligible to skip as specified by 'include class'. It must be a fully qualified class name. Multiple instances of the exclude element may be specified. The exclude child element is optional. However, when specified, the class attribute is required. |
Example:
<skippable-exception-classes>
<include class="java.lang.Exception"/>
<exclude class="java.io.FileNotFoundException"/>
</skippable-exception-classes>
The preceding example would skip all exceptions except
java.io.FileNotFoundException
, (along with any subclasses of
java.io.FileNotFoundException
).
<IP_ADDRESS>.2. Retrying Exceptions
The retryable-exception-classes element specifies a set of exceptions that chunk processing will retry. This element is a child element of the chunk element. It applies to exceptions thrown from the reader, processor, or writer batch artifacts of a chunk type step. It also applies to exceptions thrown by checkpoint commit processing. The total number of retry attempts is set by the retry-limit attribute on the chunk element. See section 8.2.1 for details on the chunk element.
The list of exceptions that will be retried (or not retried) is specified in the retryable-exception-classes element on the child include element. This list, however, may be modified using one or more child exclude elements. The rules for deciding whether to retry or not retry a given exception when a combination of include and exclude elements are used are analogous to the rules described in the discussion in section <IP_ADDRESS>.1 for skipping exceptions.
Optional Retry Listener batch artifacts can be configured on the step. A Retry Listener receives control after a retryable exception is thrown by the reader, processor, or writer. See section 9.2.8 for details on the Retry Listener batch artifact.
Syntax:
<retryable-exception-classes>
<include class="{class name}"/>
<exclude class="{class name}"/>
</retryable-exception-classes>
Where:
include class |
Specifies a class name of an exception or exception superclass to retry. It must be a fully qualified class name. Multiple instances of the include element may be specified. The include child element is optional. However, when specified, the class attribute is required. |
exclude class |
Specifies a class name of an exception or exception superclass to not retry. 'Exclude class' reduces the number of exceptions eligible for retry as specified by 'include class'. It must be a fully qualified class name. Multiple instances of the include element may be specified. The exclude child element is optional. However, when specified, the class attribute is required. |
Example:
<retryable-exception-classes>
<include class="java.io.IOException"/>
<exclude class="java.io.FileNotFoundException"/>
</retryable-exception-classes>
The result is that all IOExceptions except FileNotFoundException
(and
its subclasses) would be retried.
<IP_ADDRESS>.3. Retry and Skip the Same Exception
When the same exception is specified as both retryable and skippable, retryable takes precedence over skippable during regular processing of the chunk. While the chunk is retrying, skippable takes precedence over retryable since the exception is already being retried.
This allows an exception to initially be retried for the entire chunk and then skipped if it recurs. When retrying with default retry behavior (see section <IP_ADDRESS>.4) the skips can occur for individual items, since the retry is done with an item-count of 1.
<IP_ADDRESS>.4. Default Retry Behavior - Rollback
When a retryable exception occurs, the default behavior is for the batch runtime to rollback the current chunk and re-process it with an item-count of 1 and a checkpoint policy of item. If the optional ChunkListener is configured on the step, the onError method is called before rollback. The default retry behavior can be overridden by configuring the no-rollback-exception-classes element. See section <IP_ADDRESS>.5 for more information on specifying no-rollback exceptions.
<IP_ADDRESS>.5. Preventing Rollback During Retry
The no-rollback-exception-classes element specifies a list of exceptions that override the default behavior of rollback for retryable exceptions. This element is a child element of the chunk element. If a retryable exception is thrown the default behavior is to rollback before retry. If an exception is specified as both a retryable and a no-rollback exception, then no rollback occurs and the current operation is retried. Retry Listeners, if configured, are invoked. See section 9.2.8 for details on the Retry Listener batch artifact.
The rules for determining whether a combination of include and exclude child elements of no-rollback-exception-classes results in the "no rollback" behavior or not are analogous to the rules described in the discussion in section <IP_ADDRESS>.1 for skipping exceptions.
Syntax:
<no-rollback-exception-classes>
<include class="{class name}"/>
<exclude class="{class name}"/>
</no-rollback-exception-classes>
Where:
include class |
Specifies a class name of an exception or exception superclass for which rollback will not occur during retry processing. It must be a fully qualified class name. Multiple instances of the include element may be specified. The include child element is optional. However, when specified, the class attribute is required. |
exclude class |
Specifies a class name of an exception or exception superclass for which rollback will occur during retry processing. It must be a fully qualified class name. Multiple instances of the include element may be specified. The exclude child element is optional. However, when specified, the class attribute is required. |
<IP_ADDRESS>. Checkpoint Algorithm
The checkpoint-algorithm element specifies an optional custom checkpoint algorithm. It is a child element of the chunk element. It is valid when the chunk element checkpoint-policy attribute specifies the value 'custom'. A custom checkpoint algorithm may be used to provide a checkpoint decision based on factors other than only number of items, or amount of time. See section <IP_ADDRESS> for further information about custom checkpoint algorithms.
Syntax:
<checkpoint-algorithm ref="{name}"/>
Where:
ref |
Specifies the name of a batch artifact. |
<IP_ADDRESS>.1. Checkpoint Algorithm Properties
The 'properties' element may be specified as a child element of the checkpoint algorithm element. It is used to pass property values to a checkpoint algorithm. Any number of properties may be specified.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
Name |
Specifies a unique property name within the current scope. It must be a valid XML string value. If it matches a named property in the associated batch artifact, its value is assigned to that property. If not, it is ignored. This is a required attribute. |
Value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
8.2.2. Batchlet
The batchlet element specifies a task-oriented batch step. It is specified as a child element of the step element. It is mutually exclusive with the chunk element. See 9.1.2 for further details about batchlets. Steps of this type are useful for performing a variety of tasks that are not item-oriented, such as executing a command or doing file transfer.
Syntax:
<batchlet ref="{name}"/>
Where:
Ref |
Specifies the name of a batch artifact. |
<IP_ADDRESS>. Batchlet Exception Handling
This section is superseded by section 8.2.7.
<IP_ADDRESS>. Batchlet Properties
The 'properties' element may be specified as a child element of the batchlet element. It is used to pass property values to a batchlet. Any number of properties may be specified.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
Name |
Specifies a unique property name within the current scope. It must be a valid XML string value. If it matches a named property in the associated batch artifact, its value is assigned to that property. If not, it is ignored. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
8.2.3. Step Level Properties
The 'properties' element may be specified as a child element of the step element. It is used to expose properties to any step level batch artifact and also to the batch runtime. Any number of properties may be specified. Step level properties are available through the StepContext runtime object. See section 9.4 for further information about StepContext.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
name |
Specifies a unique property name within the current scope. It must be a valid XML string value. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
8.2.4. Step Level Listeners
Step level listeners may be configured to a job step in order to intercept step execution. The listener element may be specified as child element of the step element for this purpose. The following listener types may be specified according to step type:
-
chunk step - step listener, item read listener, item process listener, item write listener, chunk listener, skip listener, and retry listener
-
batchlet step - step listener
Multiple listeners may be configured on a step. However, there is no guarantee of the order in which they are invoked.
Syntax:
<listeners>
<listener ref="{name}">
...
</listeners>
Where:
ref |
Specifies the name of a batch artifact. |
<IP_ADDRESS>. Step Level Listener Properties
The 'properties' element may be specified as a child element of the step-level listeners element. It is used to pass property values to a step listener. Any number of properties may be specified.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
name |
Specifies a unique property name within the current scope. It must be a valid XML string value. If it matches a named property in the associated batch artifact, its value is assigned to that property. If not, it is ignored. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
Example:
<listener ref="{name}">
<properties>
<property name="Property1" value="Property1-Value"/>
</properties>
</listener>
8.2.5. Step Sequence
The first step, flow, or split defines the first step (flow or split) to execute for a given Job XML. "First" means first according to order of occurrence as the Job XML document is parsed from beginning to end. The 'next' attribute on the step, flow, or split defines what executes next. The next attribute may specify a step, flow, split, or decision. For the purpose of discussing transitioning it is convenient to group these four with the term "execution elements". The next attribute is supported on step, flow, and split elements. Steps, flows, and decisions may also use the "next" element to specify what executes next. The next attribute and next element may not be used in a way that allows for looping among job execution elements.
Syntax:
<next on="{exit status}" to="{id}" />
Where:
on |
Specifies an exit status to match to the current next element. It must be a valid XML string value. Wildcards of "" and "" may be used. "" matches zero or more characters. "" matches exactly one character. It must match an exit status value in order to have effect. This is a required attribute. |
to |
Specifies the id of another step, split, flow, or decision, which will execute next. It must be a valid XML string value. It must match an id of another step, split, flow, or decision in the same job. For a step inside a flow, the id must match another step in the same flow. This is a required attribute. |
8.2.6. Step Partitioning
A batch step may run as a partitioned step. A partitioned step runs as multiple instances of the same step definition across multiple threads, one partition per thread. The number of partitions and the number of threads is controlled through either a static specification in the Job XML or through a batch artifact called a partition mapper. Each partition needs the ability to receive unique parameters to instruct it which data on which to operate. Properties for each partition may be specified statically in the Job XML or through the optional partition mapper. Since each thread runs a separate copy of the step, chunking and checkpointing occur independently on each thread for chunk type steps.
There is an optional way to coordinate these separate units of work in a partition reducer so that backout is possible if one or more partitions experience failure. The PartitionReducer batch artifact provides a way to do that. A PartitionReducer provides programmatic control over logical unit of work demarcation that scopes all partitions of a partitioned step.
The partitions of a partitioned step may need to share results with a control point to decide the overall outcome of the step. The PartitionCollector and PartitionAnalyzer batch artifact pair provide for this need.
The 'partition' element specifies that a step is a partitioned step. The partition element is a child element of the 'step' element. It is an optional element.
Syntax:
<partition>
Example:
The following Job XML snippet shows how to specify a partitioned step:
<step id="Step1">
<chunk .../> or <batchlet ... />
<partition .../>
</step>
<IP_ADDRESS>. Partition Plan
A partition plan defines several configuration attributes that affect partitioned step execution. A partition plan specifies the number of partitions, the number of partitions to execute concurrently, and the properties for each partition. A partition plan may be defined in a Job XML declaratively or dynamically at runtime with a partition mapper.
The 'plan' element is a child element of the 'partition' element. The 'plan' element is mutually exclusive with partition mapper element. See section 9.5.1 for further details on partition mapper.
Note the specification does not attempt to guarantee order of partition execution with respect to the order within a statically or dynamically-defined plan.
Syntax:
<plan partitions="{number}" threads="{number}"/>
Where:
Partitions |
Specifies the number of partitions for this partitioned step. This is a an optional attribute. The default is 1. |
threads |
Specifies the maximum number of threads on which to execute the partitions of this step. Note the batch runtime cannot guarantee the requested number of threads are available; it will use as many as it can up to the requested maximum. This is an optional attribute. The default is the number of partitions. |
Example:
The following Job XML snippet shows how to specify a step partitioned into 3 partitions on 2 threads:
<step id="Step1">
<chunk .../>
<partition>
<plan partitions="3" threads="2"/>
</partition>
</step>
<IP_ADDRESS>. Partition Properties
When defining a statically partitioned step, it is possible to specify unique property values to pass to each partition directly in the Job XML using the property element. See section 9.5.1 for further information on partition mapper.
Syntax:
<properties partition="_partition-number_">
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
partition |
Specifies the logical partition number to which the specified properties apply. This must be a non-negative integer value, starting at 0. |
name |
Specifies a unique property name within the current scope . It must be a valid XML string value. If it matches a named property in the associated batch artifact, its value is assigned to that property. If not, it is ignored. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
Example:
The following Job XML snippet shows a step of 2 partitions with a unique value for the property named "filename" for each partition:
<partition>
<plan partitions="2">
<properties partition="0">
<property name="filename" value="/tmp/file1.txt"/>
</properties>
<properties partition="1">
<property name="filename" value="/tmp/file2.txt"/>
</properties>
</plan>
</partition>
<IP_ADDRESS>. Partition Mapper
The partition mapper provides a programmatic means for calculating the number of partitions and threads for a partitioned step. The partition mapper also specifies the properties for each partition. The mapper element specifies a reference to a PartitionMapper batch artifact; see section 9.5.1 for further information. Note the mapper element is mutually exclusive with the plan element.
Syntax:
<mapper ref="{name}">
Where:
ref |
Specifies the name of a batch artifact. |
Example:
<partition>
<mapper ref="MyStepPartitioner"/>
</partition>
<IP_ADDRESS>.1. Mapper Properties
The 'properties' element may be specified as a child element of the mapper element. It is used to pass property values to a PartitionMapper batch artifact. Any number of properties may be specified.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
name |
Specifies a unique property name within the current scope. It must be a valid XML string value. If it matches a named property in the associated batch artifact, its value is assigned to that property. If not, it is ignored. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
<IP_ADDRESS>. Partition Reducer
A partitioned step may execute with an optional partition reducer. A partition reducer provides a kind of unit of work demarcation around the processing of the partitions. Programmatic interception of the partitioned step’s lifecycle is possible through the partition reducer. The reducer element specifies a reference to a PartitionReducer batch artifact; see section 9.5.2 for further information.
The 'reducer' element is a child element of the 'partition' element.
Syntax:
<reducer ref="{name}">
Where:
ref |
Specifies the name of a batch artifact. |
Example:
<partition>
<reducer ref="MyStepPartitionReducer"/>
</partition>
<IP_ADDRESS>.1. Partition Reducer Properties
The 'properties' element may be specified as a child element of the PartitionReducer element. It is used to pass property values to a PartitionReducer batch artifact. Any number of properties may be specified.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
name |
Specifies a unique property name within the current scope. It must be a valid XML string value. If it matches a named property in the associated batch artifact, its value is assigned to that property. If not, it is ignored. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
<IP_ADDRESS>. Partition Collector
A Partition Collector is useful for sending intermediary results for analysis from each partition to the step’s Partition Analyzer. A separate Partition Collector instance runs on each thread executing a partition of the step. The collector is invoked at the conclusion of each checkpoint for chunking type steps and again at the end of partition; it is invoked once at the end of partition for batchlet type steps. A collector returns a Java Serializable object, which is delivered to the step’s Partition Analyzer. See section 9.5.4 for further information about the Partition Analyzer. The collector element specifies a reference to a PartitionCollector batch artifact; see section 9.5.3 for further information.
The 'collector' element is a child element of the 'partition' element.
Syntax:
<collector ref="{name}">
Where:
ref |
Specifies the name of a batch artifact. |
Example:
<partition>
<collector ref="MyStepCollector"/>
</partition>
<IP_ADDRESS>.1. Partition Collector Properties
The 'properties' element may be specified as a child element of the collector element. It is used to pass property values to a PartitionCollector batch artifact. Any number of properties may be specified.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
name |
Specifies a unique property name within the current scope. It must be a valid XML string value. If it matches a named property in the associated batch artifact, its value is assigned to that property. If not, it is ignored. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
<IP_ADDRESS>. Partition Analyzer
A Partition Analyzer receives intermediary results from each partition sent via the step’s Partition Collector. A Partition analyzer runs on the step main thread and serves as a collection point for this data. The PartitionAnalyzer also receives control with the partition exit status for each partition, after that partition ends. An analyzer can be used to implement custom exit status handling for the step, based on the results of the individual partitions. The analyzer element specifies a reference to a PartitionAnalyzer batch artifact; see section 9.5.4 for further information.
Syntax:
<analyzer ref="{name}">
Where:
ref |
Specifies the name of a batch artifact. |
Example:
<partition>
<analyzer ref="MyStepAnalyzer"/>
</partition>
<IP_ADDRESS>.1. Partition Analyzer Properties
The 'properties' element may be specified as a child element of the analyzer element. It is used to pass property values to a PartitionAnalyzer batch artifact. Any number of properties may be specified.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
name |
Specifies a unique property name within the current scope. It must be a valid XML string value. If it matches a named property in the associated batch artifact, its value is assigned to that property. If not, it is ignored. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
8.2.7. Step Exception Handling
Any unhandled exception thrown by any step-level artifact during step processing causes the step to terminate with a batch status of FAILED. In this context, "unhandled" means an exception thrown by the execution of the artifact back to the runtime implementation which does not result in a skip or a retry as described in section <IP_ADDRESS>. See section 8.9.2 for complete details on transitioning after an unhandled exception.
8.3. Flow
A flow defines a sequence of execution elements that execute together as a unit. When the flow is finished, it is the entire flow that transitions to the next execution element. A flow may transition to a step, split, decision, or another flow. A flow may contain step, flow, decision, and split execution elements. See section 8.5 for more on decisions. See section 8.4 for more on splits. The execution elements within a flow may only transition among themselves; they may not transition to elements outside of the flow. A flow may also contain the transition elements next, stop, fail, and end. See section 8.6 for more on transition elements.
Syntax:
<flow id="{name}"next="{flow-id|step-id|split-id|decision-id}">
<step> ... </step> ...
</flow>
Where:
id |
Specifies the logical name of the flow and is used for identification purposes. It must be a valid XML string value. This is a required attribute. |
next |
Specifies the next step, flow, split, or decision to run after this step is complete. It must be a valid XML string value. This is an optional attribute. The default is this flow is the last execution element in the job. Note: next attributes cannot be specified such that a loop occurs among steps. |
8.4. Split
A split defines a set of flows that execute concurrently. A split may include only flow elements as children. See section 8.3 for more on flows. Each flow runs on a separate thread. The split is finished after all flows complete. When the split is finished, it is the entire split that transitions to the next execution element. A split may transition to a step, flow, decision, or another split.
Syntax:
<split id="{name}"next="{flow-id|step-id|split-id|decision-id}">
<flow> ... </flow>
...
</split>
Where:
id |
Specifies the logical name of the split and is used for identification purposes. It must be a valid XML string value. This is a required attribute. |
next |
Specifies the next step, flow, split, or decision to run after this step is complete. It must be a valid XML string value. This is an optional attribute. The default is this split is the last execution element in the job. Note: next attributes cannot be specified such that a loop occurs among steps. |
8.4.1. Split Termination Processing Incomplete
The effort of the initial 1.0 final release specification to define split termination processing is recognized as incomplete. This is related to the recognition that flow transitioning is incomplete (section 8.9.5).
As such, there is no well-defined mechanism for "passing back" status from the individual child flows of a split and aggregating them into a status at the split level. There is, accordingly, no termination based on the status of the constituent flows performed after a split execution.
However, the implementor must be aware that a split may have a child flow where the flow itself or a flows child (step, decision, etc.) causes the job execution to terminate. This could be via an end, stop, or fail transition element, or via an unhandled exception.
In such a case the job should then cease execution before transitioning past the current, containing split, on to the next execution element.
Typically only one such element (in one single flow) would terminate job execution, with a corresponding batch and exit status that would then be set by the implementation as the job-level batch status and exit status, since typically the whole split would be intended to complete.
The spec does not make an effort, then, to define the outcome if more than one flow within a split produced a terminating status. A suggestion, though, is that a FAILED batch status should be given preference to STOPPED, which should be given preference to COMPLETED status, and a natural corollary might be to bubble up the associate exit status as the job-level exit status as well.
8.5. Decision
A decision provides a customized way of determining sequencing among steps, flows, and splits. The decision element may follow a step, flow, or split. A job may contain any number of decision elements. A decision element is the target of the "next" attribute from a job-level step, flow, split, or another decision. A decision must supply a decider batch artifact (see section 9.6). The decider’s purpose is to decide the next transition. The decision uses any of the transition elements, stop, fail, end, and next elements to select the next transition. See section 8.6 for further information on transition elements. The decider return value will also be set as the current value of the job exit status, in addition to being matched against the decisions own child transition elements to decide the next transition.
Syntax:
<decision id="{name}" ref="{ref_-_name}">
Where:
id |
Specifies the logical name of the decision and is used for identification purposes. It must be a valid XML string value. This is a required attribute. |
ref |
Specifies the name of a batch artifact. |
Example:
<decision id="AfterFlow1" ref="MyDecider">
...
</decision>
8.5.1. Decision Properties
The 'properties' element may be specified as a child element of the decision element. It is used to pass property values to a decider. Any number of properties may be specified.
Syntax:
<properties>
<property name="{property-name}" value="{name-value}"/>
</properties>
Where:
name |
Specifies a unique property name within the current scope. It must be a valid XML string value. If it matches a named property in the associated batch artifact, its value is assigned to that property. If not, it is ignored. This is a required attribute. |
value |
Specifies the value corresponding to the named property. It must be a valid XML string value. This is a required attribute. |
8.6. Transition Elements
Transition elements may be specified in the containment scope of a step, flow, or decision (but not a split) to direct job execution sequence or to terminate job execution. There are fo ur transition elements:
-
next - directs execution flow to the next execution element.
-
fail - causes a job to end with FAILED batch status.
-
end - causes a job to end with COMPLETED batch status.
-
stop - causes a job to end with STOPPED batch status.
Fail, end, and stop are considered "terminating elements" because they cause a job execution to terminate.
8.6.1. Next Element
The next element is used to transition execution to the next execution element. Multiple next elements may be specified in the current containment scope. Syntax:
<next on="{exit status}" to="{step id_|_flow id_|_split id}"/>
Where:
on |
Specifies the exit status value that activates this end element. It must be a valid XML string value. Wildcards of "" and "" may be used. "" matches zero or more characters. "" matches exactly one character. It must match an exit status value in order to have effect. This is a required attribute. |
to |
Specifies the execution element to which to transition after this decision. It must be a valid XML string value. This is a required attribute. Note: the to value cannot specify the next execution element such that a loop occurs in the batch job. |
Example:
<step id="Step1">
<next on="*" to="Step2"/>
</step>
8.6.2. Fail Element
The fail element is used to terminate the job at the conclusion of the current step or flow. The job batch status is set to FAILED. This does not, however, directly affect the batch status of the step containing the fail element. Multiple fail elements may be specified in the current containment scope. The fail element is supported as a child of the step, flow, and decision elements.
Syntax:
<fail on="{exit status}" exit-status="{exit status}"/>
Where:
on |
Specifies the exit status value that activates this fail element. It must be a valid XML string value. Wildcards of "" and "" may be used. "" matches zero or more characters. "" matches exactly one character. It must match an exit status value in order to have effect. This is a required attribute. |
exit-status |
Specifies the new exit status for the job. It must be a valid XML string value. This is an optional attribute. If not specified, the job-level exit status is unchanged. This attribute does not directly change any step exit status (particularly the step which contains this fail element). |
Example:
<step id="Step1">
<fail on="FAILED" exit-status="EARLY COMPLETION"/>
</step>
8.6.3. End Element
The end element is used to terminate the job at the current step. The job batch status is set to COMPLETED. This does not, however, directly affect the batch status of the step containing the end element. Multiple end elements may be specified in the current containment scope. The end element is supported as a child of the step, flow, and decision elements.
Syntax:
<end on="{exit status}" exit-status="{exit status}"/>
Where:
on |
Specifies the exit status value that activates this end element. It must be a valid XML string value. Wildcards of "" and "" may be used. "" matches zero or more characters. "" matches exactly one character. It must match an exit status value in order to have effect. This is a required attribute. |
exit-status |
Specifies the new exit status for the job. It must be a valid XML string value. This is an optional attribute. If not specified, the job-level exit status is unchanged. This attribute does not directly change any step exit status (particularly the step which contains this end element). |
Example:
<step id="Step1">
<end on="COMPLETED" exit-status="EARLY COMPLETION">
</step>
8.6.4. Stop Element
The stop element is used to terminate the job after the current step or flow. If the stop element matches the exit status, the job-level batch status is then set to STOPPED. This does not, however, directly affect the batch status of the step containing the . Multiple stop elements may be specified in the current containment scope. The stop element is supported as a child of step, flow, and decision elements.
<stop on="{exit status}" exit-status="{exit status}" restart="{step id_|_flow id_|_split id}"/>
Where:
on |
Specifies the exit status value that activates this end element. It must be a valid XML string value. Wildcards of "" and "" may be used. "" matches zero or more characters. "" matches exactly one character. It must match an exit status value in order to have effect. This is a required attribute. |
exit-status |
Specifies the exit status for the job. It must be a valid XML string value. This is an optional attribute. If not specified, the job-level exit status is unchanged. This attribute does not directly change any step exit status (particularly the step which contains this stop element). |
restart |
Specifies the job-level step, flow, or split at which to restart when the job is restarted. It must be a valid XML string value. This is an optional attribute. |
Example:
<step id="Step1">
<stop on="COMPLETED" restart="step2"/>
</step>
8.7. Batch and Exit Status
Batch execution reflects a sequence of state changes, culminating in an end state after a job has terminated. These state changes apply to the entire job as a whole, as well as to each step within the job. These state changes are exposed through the programming model as status values. There is both a runtime status value, called "batch status", as well as a user-defined value, called "exit status".
A job and each step in a job end with a batch status and exit status value. Batch status is set by the batch runtime; exit status may be set through the Job XML or by the batch application. The exit status for a job and a step will be initially set to null. At the time that the job or step completes execution, if the exit status is equal to null, it will then be set by the runtime implementation to the string value of the batch status, which will be its final value. The batch and exit status values are available in the JobContext and StepContext runtime objects, and the exit status can be set explicitly via any batch artifact. The overall batch and exit status for the job are available through the JobOperator interface. Batch and exit status values are strings. The following batch status values are defined:
Value |
Meaning |
STARTING |
Batch job has been passed to the batch runtime for execution through the JobOperator interface start or restart operation. A step has a status of STARTING before it actually begins execution. |
STARTED |
Batch job has begun execution by the batch runtime. A step has a status of STARTED once it has begun execution. |
STOPPING |
Batch job has been requested to stop through the JobOperator interface stop operation or by a <stop> element in the Job XML. A step has a status of STOPPING as soon as JobOperator.stop receives control. |
STOPPED |
Batch job has been stopped through the JobOperator interface stop operation or by a <stop> element in the Job XML. A step has a status of STOPPED once it has actually been stopped by the batch runtime. |
FAILED |
Batch job has ended due to an unresolved exception or by a <fail> element in the Job XML. A step has a status of FAILED under the same conditions. |
COMPLETED |
Batch job has ended normally or by an <end> element in the Job XML. A step has a status of COMPLETED under the same conditions. |
ABANDONED |
Batch job has been marked abandoned through the JobOperator interface abandon operation. An abandoned job is still visible through the JobOperator interface, but is not running, nor can it be restarted. It exists only as a matter of history. |
A job execution will end under the following conditions:
-
A job-level execution element (step, flow, or split) finishes execution, without specifying a "next" attribute and without the exit status matching any transition elements. (See section 8.9.2 for details). In this case, the batch status is set to COMPLETED.
-
A step throws an exception to the batch runtime that does not match skip or retry criteria, with the exit status not matching any transition elements. In this case, the batch status is set to FAILED. (See section 8.9.2 for details). In the case of partitioned or concurrent (split) step execution, all other still-running parallel instances are allowed to complete before the job ends with FAILED batch status.
-
A step, flow, or decision terminates execution with a stop, end, or fail element. In this case, the batch status is STOPPED, COMPLETED, or FAILED, respectively .
The batch and exit status of the job is set as follows:
-
Batch status is initially set to STARTING by the batch runtime. Immediately before starting the first step, the batch runtime sets the batch status to STARTED .
-
Exit status can be overridden by any artifact by invoking the exit status setter method on the JobContext object.
-
Exit status can be overridden by a decision element.
-
Exit status can be overridden by a terminating transition element on a step, flow, or split. See section 8.6.
-
Final batch status is set by the batch runtime depending on the outcome of the job. See table above. Exit status is set to the final batch status if it was not overridden by any of the override means described earlier in this list. Note the last override to set exit status during the course of job execution takes precedence over all others.
In addition to these conditions and events which are well-defined by this specification, it is also recognized that the runtime may be forced to make another transition of job and step batch status.
For example, a JVM hang may cause a job to appear in STARTED state even though it is no longer running. The specification forbids running multiple executions of a given job instance at the same time. In order to recover and allow restart it is expect that a batch runtime implementation might provide a mechanism to automatically or through user intervention mark the appropriate job and step execution(s) as FAILED (i.e. set the batch status as FAILED).
The details are left entirely to the implementation, we are just recognizing here that this is a valid state transition.
8.7.1. Batch and Exit Status for Steps
Step batch status is set initially, and then again at the conclusion of the step, by the batch runtime. Step exit status is initially set to the same value as batch status. Step exit status may be set by any batch artifact configured to the step by invoking the exit status setter method in the StepContext object. See section 9.4 for further information about the StepContext object. Setting the step exit status does not alter the execution of the current step, but rather, is available to influence the execution of subsequent steps via transition elements (see 8.6) and deciders (see 9.6). If no batch artifact sets the exit status, the batch runtime will default the value to the string form of the batch status value of the step when step execution completes. An important point to note is that transition elements do not affect the batch and exit status of their containing step (for a step with one or more child transition elements), but only potentially affect the batch and exit status of the job.
Example:
<step id="FS1">
<batchlet >
<next on="RC0" />
<fail on="RC4" exit-status="BAD"/>
<fail on="RC8" />
</step>
Suppose for the above example JSL snippet, FS1s batchlet executes normally with an exit status of "RC4". Then step FS1s batch status will end up as COMPLETED, and FS1s exit status will end up as "RC4". The jobs batch status will end up as FAILED and the jobs exit status will end up as "BAD". Likewise, if the batchlet completes with an exit status of "RC8" the steps batch and exit status will be COMPLETED and "RC8", respectively, while the jobs batch and exit status will be FAILED and "FAILED" (assuming the job exit status hasnt been set and defaults in this case).
Note the implications for restart processing. For example, a completed step wont re-run just because the step includes a transition element failing the job on the original step executions exit status. See section 10.8 for more on restart processing.
8.7.2. Exit Status for Partitioned Steps
The exit status for a partitioned step follows the same rules as for a regular step except for an exit status set by batch artifacts processing individual partitions . This means any batch artifact running on the main thread of the partitioned step can set the steps exit status via the exit status setter method on the StepContext object , the same as for a non-partitioned step.E.g. a steps partition analyzer, partition reducer, or step listener could each potentially set the steps exit status in this simple manner (since each of these artifacts run on the initial thread, not the threads processing an individual partition). If the exit status is not set it defaults to batch status at the end of step execution , the same as for a non-partitioned step.
For a partitioned batchlet, each thread processing a partition may return a separate exit status. However, these exit status values are ignored unless a partition analyzer is used to coalesce these separate exit status values into a final exit status value for the step.
The batch runtime maintains a StepContext clone per partition. For a partitioned batchlet or chunk, any batch artifact running on any of the threads processing a partition would merely set a separate exit status through the StepContext clone. These exit status values are ignored unless a partition analyzer is used to coalesce these separate exit status values into a final exit status value for the step.
8.8. Job XML Substitution
Job XML supports substitution as part of any attribute value. The following expression language is supported on all attributes:
<attribute-value> ::= ' " ' <principle-value-expression>[<default-expression>] ' " ' <principle-value-expression> ::= <value-expression> <value-expression> ::= "#\{"<operator-expression>"}" | <string-literal>[ <value-expression> ] <default-expression> ::= ":" <value-expression> ";" <operator-expression> ::= <operator1> | <operator2> | <operator3> |<operator4> | <operator5> <operator1> ::= "jobParameters" "[" <target-name> "]" <operator2> ::= "jobProperties" "[" <target-name> "]" <operator3> ::= "systemProperties" "[" <target-name> "]" <operator4> ::= "partitionPlan" "[" <target-name> "]" <target-name> ::= " ' " <string-literal> " ' " <string-literal> is a valid XML string value.
8.8.1. Substitution Processing Rules
Substitution expressions are processed for both initial job start and on job restart. All substitution expressions must be resolved before the job can be started or restarted, except for the partitionPlan operator, which has deferred resolution - see section <IP_ADDRESS> for more on that. After substitution expression resolution, the resultant XML document must be checked for validity, according to the guidelines outlined in section 13, Job Specification Language XSD.
A substitution expression may reference a job parameter or a job property by specifying the name of the parameter or property through a substitution expression operator. This name is referred to generally in substitution expression syntax as a "target name". There are four substitution operators:
-
jobParameters - specifies to use a named parameter from the job parameters.
-
jobProperties - specifies to use a named property from among the job’s properties.
-
systemProperties - specifies to use a named property from the system properties.
-
partitionPlan - specifies to use a named property from the partition plan of a partitioned step.
<IP_ADDRESS>. jobParameters Substitution Operator
The jobParameters substitution operator resolves to the value of the job parameter with the specified target name.
<IP_ADDRESS>. jobProperties Substitution Operator
The jobProperties substitution operator resolves to the value of the job property with the specified target name. This property is found by recursively searching from the innermost containment scope (this includes earlier properties within the current scope) to the outermost scope until a property with the specified target name is found.
E.g. The batch runtime would attempt resolution of the jobProperties operator specification in each of the two following reader property definitions by first searching for earlier property definitions within the reader properties collection, then the step properties collection (there are none in this example), then the job properties collection (if any). The search stops at the first occurrence of the specified target name.
<job id="job1">
<properties>
<property name="filestem" value="postings"/>
<property name="outputlog" value="jobmessages"/>
</properties>
<step id="step1">
<chunk>
<reader ref="MyReader">
<properties>
<property name="infile.name" value="#\{jobProperties['filestem']}.txt"/>
<property name="outputlog" value="readermessages"/>
<property name="outfile.name" value="#\{jobProperties['outputlog']}.txt"/>
</properties>
</reader>
</chunk>
</step>
</job>
The resolved value for reader property "infile.name" would be "postings.txt".
The resolved value for reader property "outfile.name" would be "readermessages.txt".
<IP_ADDRESS>. systemProperties Substitution Operator
The systemProperties substitution operator resolves to the value of the system property with the specified target name.
<IP_ADDRESS>. partitionPlan Substitution Operator
The partitionPlan substitution operator resolves to the value of the partition plan property with the specified target name from the PartitionPlan returned by the PartitionMapper. Partition plan properties are in scope only for the step to which the partition plan is defined. The partitionPlan operator is resolved separately for each partition before the partition execution begins.
E.g. Given job, job1:
<job id="job1">
<step id="step1">
<chunk>
<reader ref="MyReader>
<properties>
<property name="infile.name" value="file#\{partitionPlan['myPartitionNumber']}.txt"/>
<property name="outfile.name" value="#\{partitionPlan['outFile']}"/>
</properties>
</reader>
<writer ref="MyWriter"/>
</chunk>
<partition>
<mapper ref="MyMapper "/>
</partition>
</step>
</job>
And MyMapper implementation:
public class MyMapper implements PartitionMapper \{
public PartitionPlan mapPartitions() \{
PartitionPlanImpl pp= new PartitionPlanImpl();
pp.setPartitions(2);
Properties p0= new Properties();
p0.setProperty("myPartitionNumber", "0");
p0.setProperty("outFile", "outFileA.txt");
Properties p1= new Properties();
p1.setProperty("myPartitionNumber", "1");
p1.setProperty("outFile", "outFileB.txt");
Properties[] partitionProperties= new Properties[2];
partitionProperties[0]= p0;
partitionProperties[1]= p1;
pp.setPartitionProperties(partitionProperties);
return pp;
}
}
The step1 chunk would run as two partitions, with the itemReader property "infile.name" resolved to "file0.txt" and "file1.txt" for partitions 0 and 1, respectively. Also, itemReader property "outfile.name" would resolve to "outFileA.txt", and "outFileB.txt" for partitions 0 and 1, respectively.
<IP_ADDRESS>. Substitution Expression Default
Substitutions expressions may include a default value using the ":" operator. The default is applied if the substitution’s principle value expression resolves to the empty string "".
<IP_ADDRESS>. Property Resolution Rule
Properties specified by a substitution operator must be defined before they can be used in a substitution expression.
Examples:
Resolvable Property Reference
The batch runtime will resolve a substitution reference to a property that occurs before it is referenced. In the following example, property "infile.name" is defined before it is used to form the value of property "tmpfile.name". This is a resolvable reference.E.g.
<property name="infile.name" value="in.txt" />
<property name="tmpfile.name" value="#\{jobProperties['infile.name']}.tmp" />
The batch runtime resolves a resolvable reference with the resolved value of the specified property reference.
Unresolvable Property Reference
The batch runtime will not resolve a substitution reference to a property whose first occurrence is after it is referenced. In the following example, property "infile.name" is defined after it is used to form the value of property "tmpfile.name". This is a unresolvable reference.E.g.
<property name="tmpfile.name" value="in.txt#\{jobProperties[infile.name]}" />
<property name="infile.name" value="in.txt" />
The batch runtime resolves an unresolvable reference in XML to the empty string "".
<IP_ADDRESS>. Undefined Target Name Rule
A substitution expression operator that specifies an undefined target name is assigned the empty string in XML.
<IP_ADDRESS>. Job Restart Rule
Job Parameters may be specified on job restart. Substitution expression resolution occurs on each restart. This makes it possible for new values to be used in Job XML attributes during job restart. While all substitution expressions resolve the same way on restart as on initial start, there is a special rule for the number of partitions in a partitioned step:
The number of partitions in a partition plan
The batch runtime determines the number of partitions in a partitioned step the first time the step is attempted. The batch runtime remembers that decision and applies it to that step on the next job execution, once the previous job execution is restarted. The decision cannot be altered by a substitution expression. The decision can be altered, however, through a PartitionMapper artifact by specifying the "override" option in the PartitionPlan object. See section 10.9.4 for details on the PartitionPlan class.
8.8.2. Examples
<property name="infile.name" value="in.txt" />
Resolved property: infile.name="in.txt"
<property name="infile.name" value="#\{jobParameters['infile.name']}" />
Resolved property: infile.name= value of infile.name job parameter
<property name="infile.name" value="#\{systemProperties['infile.name']}" />
Resolved property: infile.name= value of infile.name system property
<property name="infile.name" value="#\{jobProperties['infile.name']}" />
Resolved property: infile.name= value of infile.name job property
<property name="infile.name" value="#\{partitionPlan['infile.name']}" />
Resolved property: infile.name= value of infile.name from partition plan for the current partition
<property name="infile.name" value="#\{jobParameters['infile.name']}:in.txt;" />
Resolved property: infile.name = value of infile.name job parameter or "in.txt" if infile.name job parameter is unspecified.
8.9. Transitioning Rules
8.9.1. Combining Transition Elements
Any combination of transition elements can be included at the end of a step, flow, or decision definition. Combinations can include zero, one, or more than one instance of a single type of execution element,E.g. next.
Transition elements are evaluated in sequential order as they occur within the JSL document. I.e. the appropriate exit status is compared with the on attribute value of the first transition element in the sequence and, if it matches, then the corresponding transition is perfomed, and the rest of the transition elements are ignored. If not, the second transition element is evaluated, etc.
Example:
<step id="Step1">
<next on="RC0" to="Step2"/>
<next on="RC4" to="Step3"/>
<end on="RC4" exit-status="DONE"/>
<fail on="*"/> <!-- Matches anything, so only makes sense as last transition element-->
</step>
8.9.2. Transitioning Precedence Rules
The transition elements are always "evaluated" first, and if a match is found, execution transitions accordingly (either to another execution element or the job is stopped or failed).
If a match is not found among the transition elements (which would always be the case if there are no transition elements), then transition proceeds as follows:
-
If execution resulted in an unhandled exception, then the job ends with batch status of FAILED.
-
If execution ended normally, and the execution element whose execution is completing contains a next attribute, then execution transitions to the element named by this next attribute value.
-
If execution ended normally, and the execution element whose execution is completing does not contain a next attribute, then the job ends normally (with COMPLETED batch status). For transitioning from a step within a flow, this statement doesnt apply. See section 8.9.4 for details.
The following examples illustrate how the above rules might be employed:
Example 1: Transition to Step2, unless exit status of RC_ABORT seen, in which case fail the job
<step id="Step1" next="Step2">
<fail on="RC_ABORT" exit-status="ABORTED"/>
</step>
Example 2: Transition to Step2, but if exception thrown, transition to RecoveryStep.
<step id="Step1" next="Step2">
<!-- Assumes step exit status defaults to step batch status (FAILED)-->
<next on="FAILED" to="RecoveryStep"/>
<fail on="*"/>
</step>
Note that the second example shows it is possible for a job to executed to COMPLETED status, even though a constituent step ends with FAILED batch status (See section 8.2.7).
8.9.3. Loop definition
The specification prohibits next and to attribute values that result in a "loop". More precisely, this means that no execution element can be transitioned to twice within a single job execution.
This wording is purposely written this way rather than merely saying no execution element can be executed twice within a single job execution. Say "step1" executed to completion during an initial execution which ultimately failed, and upon restart we transitioned past "step1" without executing it since it had already completed, but we subsequently transitioned (back) to "step1". This may only be a single execution of "step1" during a single job execution, but it still violates the looping prohibition.
The runtime may detect potential loops in an initial validation phase, as described in section 13.1, or may only detect loops once they occur.
8.9.4. Transitioning From Within Flows
-
As mentioned in section 8.3, an execution element which is a child of a flow may only transition to another execution element within the same flow. The flows transition elements, however, would transition execution to the next execution element at the level of the execution scope containing the flow ,E.g. the job.
-
For terminating transitions (stop, end, fail) as well as failures caused by unhandled exceptions, it is the entire job execution which is terminated. It is not just the case that the flow alone is somehow failed or ended yet with another level of transitioning occurring at the containing (e.g. job) level.
-
Note: transition via next outside of the flow is not permitted. If this is not detected during job validation (see section 13.1), then at runtime the job execution will end at this point with batch status of FAILED.
-
-
When a child of a flow completes normally, and when there are no matching transition elements as well as no next attribute at the level of this child of a flow, then the flow ends.
Another way of stating rules #2 and #3 in this section would be to say that all the rules in section 8.9.2 apply to transitions within flows (i.e. among children of flows) and are effective at the job level, except for rule #3 in section 8.9.2 (this case does not necessarily end the job).
See the example at the end of section 8.9.5 for further clarification.
8.9.5. Flow-level Transitions Undefined
It is recognized that the specification is incomplete with respect to how exactly flow transition elements are evaluated. Though the list in section 10.8.4 has an assertion in rule 3.e. that suggests using the exit status of the last contained execution element as a flow-level exit status, this does not seem to be a complete definition. For example, what if the last execution element within the flow is a split
This might be rectified in a later revision of this specification. In the meantime it is suggested to avoid using flow-level transition elements in light of this ambiguity.
On the other hand, a transition from a flow via the next attribute of the flow element is well-defined at the current spec level, and is suggested.
Example:
<flow id="Flow1" next="StepX">
<step id="FS1">
<next on="RC1" to="FS2A"/>
<next on="RC2" to="FS2B"/>
<!-- ILLEGAL - would be illegal, since one can only transition within the flow
<next on="RC3" to="StepX"/>
-->
</step>
<step id="FS2A" >
<fail on="FAILED"/> <!-- FAILS job, doesn't "fail flow"-->
</step>
<step id="FS2B" >
<fail on="FAILED"/> <!-- FAILS job, doesn't "fail flow"-->
</step>
<next on="F*" to="StepY"/> <!-- UNDEFINED -->
</flow>
<step id="StepX">
As noted in the comments inline, this example makes the following points:
-
that a child of a flow can only transition to another child of the same flow (Item 1. in section 8.9.4)
-
that a terminating transition terminates the job, not just the flow somehow (Item 2. in section 8.9.4)
-
that a transition element which is a direct child of the flow itself is currently UNDEFINED (section 8.9.5)
9. Batch Programming Model
The batch programming model is described by interfaces, abstract classes, and field annotations. Interfaces define the essential contract between batch applications and the batch runtime. Most interfaces have a corresponding abstract class that provides default implementations of certain methods for developer convenience.
9.1. Steps
A batch step is either chunk or batchlet.
9.1.1. Chunk
A chunk type step performs item-oriented processing using a reader-processor-writer batch pattern and does checkpointing.
<IP_ADDRESS>. ItemReader Interface
An ItemReader is used to read items for a chunk step. ItemReader is one of the three batch artifact types that comprise a chunk type step. The other two are ItemProcessor and ItemWriter.
The ItemReader interface may be used to implement an ItemReader batch artifact:
package jakarta.batch.api.chunk;
import java.io.Serializable;
/*
* ItemReader defines the batch artifact that reads
* items for chunk processing.
*/
public interface ItemReader {
/**
* The open method prepares the reader to read items
* The input parameter represents the last checkpoint
* for this reader in a given job instance. The
* checkpoint data is defined by this reader and is
* provided by the checkpointInfo method. The checkpoint
* data provides the reader whatever information it needs
* to resume reading items upon restart. A checkpoint value
* of null is passed upon initial start.
*
* @param checkpoint specifies the last checkpoint
* @throws Exception is thrown for any errors.
*/
public void open(Serializable checkpoint) throws Exception;
/**
* The close method marks the end of use of the
* ItemReader. The reader is free to do any cleanup
* necessary.
* @throws Exception is thrown for any errors.
*/
public void close() throws Exception;
/**
* The readItem method returns the next item
* for chunk processing.
* It returns null to in dicate no more items, which
* also means the current chunk will be committed and
* the step will end.
* *@return* next item or null
* @throws Exception is thrown for any errors.
*/
public Object readItem() throws Exception;
/**
* The checkpointInfo method returns the current
* checkpoint data for this reader. It is
* called before a chunk checkpoint is committed.
* *@return* checkpoint data
* @throws Exception is thrown for any errors.
*/
public Serializable checkpointInfo() throws Exception;
}
package jakarta.batch.api.chunk;
import java.io.Serializable;
public abstract class AbstractItemReader implements ItemReader
{
@Override
public void open(Serializable checkpoint)throws Exception {
}
@Override
public void close()throws Exception {
}
@Override
public abstract Object readItem() throws Exception;
@Override
public Serializable checkpointInfo() throws Exception {
return null;
}
}
<IP_ADDRESS>. ItemProcessor Interface
An ItemProcessor is used to process items for a chunk step. ItemProcessor is one of the three batch artifact types that comprise a chunk type step. An ItemProcessor is an optional artifact on a chunk type step. The other two are ItemReader and ItemWriter.
The ItemProcessor interface may be used to implement an ItemProcessor batch artifact:
package jakarta.batch.api.chunk;
/**
* ItemProcessor is used in chunk processing
* to operate on an input item and produce
* an output item.
*
*/
public interface ItemProcessor {
/**
* The processItem method is part of a chunk
* step. It accepts an input item from an
* item reader and returns an item that gets
* passed onto the item writer. Returning null
* indicates that the item should not be continued
* to be processed. This effectively enables processItem
* to filter out unwanted input items.
* @param item specifies the input item to process.
* *@return* output item to write.
* @throws Exception thrown for any errors.
*/
public Object processItem(Object item) throws Exception;
}
<IP_ADDRESS>. ItemWriter Interface
An ItemWriter is used to write a list of output items for a chunk step. ItemWriter is one of the three batch artifact types that comprise a chunk type step. The other two are ItemProcessor and ItemReader.
The ItemWriter interface may be used to implement an ItemWriter batch artifact:
package jakarta.batch.api.chunk;
import java.io.Serializable;
import java.util.List;
/**
*
* ItemWriter defines the batch artifact that writes to a
* list of items for chunk processing.
*
*/
public interface ItemWriter {
/**
* The open method prepares the writer to write items.
*
* The input parameter represents the last checkpoint
* for this writer in a given job instance. The
* checkpoint data is defined by this writer and is
* provided by the checkpointInfo method. The checkpoint
* data provides the writer whatever information it needs
* to resume writing items upon restart. A checkpoint value
* of null is passed upon initial start.
*
* @param checkpoint specifies the last checkpoint
* @throws Exception is thrown for any errors.
*/
public void open(Serializable checkpoint) throws Exception;
/**
* The close method marks the end of use of the
* ItemWriter. The writer is free to do any cleanup
* necessary.
* @throws Exception is thrown for any errors.
*/
public void close() throws Exception;
/**
* The writeItems method writes a list of item
* for the current chunk.
* @param items specifies the list of items to write.
* This may be an empty list (e.g. if all the
* items have been filtered out by the
* ItemProcessor).
* @throws Exception is thrown for any
errors.
*/
public void writeItems(List<Object> items) throws Exception;
/**
* The checkpointInfo method returns the current
* checkpoint data for this writer. It is
* called before a chunk checkpoint is committed.
* *@return* checkpoint data
* @throws Exception is thrown for any errors.
*/
public Serializable checkpointInfo() throws Exception;
}
package jakarta.batch.api.chunk;
import java.io.Serializable;
import java.util.List;
/**
* The AbstractItemWriter provides default implementations
* of not commonly implemented methods.
*/
public abstract class AbstractItemWriter implements ItemWriter
{
/**
* Override this method if the ItemWriter requires
* any open time processing.
* The default implementation does nothing.
*
* @param last checkpoint for this ItemReader
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void open(Serializable checkpoint) throws Exception {
}
/**
* Override this method if the ItemWriter requires
* any close time processing.
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void close() throws Exception {
}
/**
* Implement write logic for the ItemWriter in this
* method.
*
* @param items specifies the list of items to write.
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public abstract void writeItems(List<Object> items) throws
Exception;
/**
* Override this method if the ItemWriter supports
* checkpoints.
* The default implementation returns null.
*
* *@return* checkpoint data
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public Serializable checkpointInfo() throws Exception {
return null;
}
}
<IP_ADDRESS>. CheckpointAlgorithm Interface
A CheckpointAlgorithm implements a custom checkpoint policy for a chunk step. The CheckpointAlgorithm interface may be used to implement an CheckpointAlgorithm batch artifact:
package jakarta.batch.api.chunk;
/**
* CheckpointAlgorithm provides a custom checkpoint
* policy for chunk steps.
*
*/
public interface CheckpointAlgorithm {
/**
* The checkpointTimeout is invoked at the beginning of a new
* checkpoint interval for the purpose of establishing the checkpoint
* timeout.
* It is invoked before the next chunk transaction begins. This
* method returns an integer value, which is the timeout value
* (expressed in seconds) which will be used for the next chunk
* transaction.
* This method is useful to automate the setting of the
* checkpoint timeout based on factors known outside the job
* definition.
* A value of '0' signifies no maximum established by this
* CheckpointAlgorithm, i.e. the maximum permissible timeout allowed by
* the runtime environment.
* @return the timeout interval (expressed in seconds)
* to use for the next checkpoint interval
* @throws Exception thrown for any errors.
*/
public int checkpointTimeout() throws Exception;
/**
* The beginCheckpoint method is invoked before the
* next checkpoint interval begins (before the next
* chunk transaction begins).
* @throws Exception thrown for any errors.
*/
public void beginCheckpoint() throws Exception;
/**
* The isReadyToCheckpoint method is invoked by
* the batch runtime after each item is processed
* to determine if now is the time to checkpoint
* the current chunk.
* *@return* boolean indicating whether or not
* to checkpoint now.
* @throws Exception thrown for any errors.
*/
public boolean isReadyToCheckpoint() throws Exception;
/**
* The endCheckpoint method is invoked after the
* last checkpoint is taken (after the chunk
* transaction is committed).
* @throws Exception thrown for any errors.
*/
public void endCheckpoint() throws Exception;
}
package jakarta.batch.api.chunk;
/**
* The AbstractCheckpointAlgorithm provides default
* implementations of less commonly implemented
* methods.
*/
public abstract class AbstractCheckpointAlgorithm implements
CheckpointAlgorithm {
/**
* Override this method if the CheckpointAlgorithm
* establishes a checkpoint timeout.
* The default implementation returns 0, which means
* the maximum permissible timeout allowed by the
* runtime environment.
*
* @return the timeout interval (expressed in seconds)
* to use for the next checkpoint interval
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public int checkpointTimeout() throws Exception {
return 0;
}
/**
* Override this method for the CheckpointAlgorithm
* to do something before a checkpoint interval
* begins (before the next chunk transaction begins).
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void beginCheckpoint() throws Exception {
}
/**
* Implement logic in this method
* to decide if a checkpoint should be taken now.
*
* *@return* boolean indicating whether or not
* to checkpoint now.
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public abstract boolean isReadyToCheckpoint() throws Exception;
/**
* Override this method for the CheckpointAlgorithm
* to do something after a checkpoint is taken (after
* the chunk transaction is committed).
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void endCheckpoint() throws Exception {
}
}
9.1.2. Batchlet Interface
A Batchlet-type step implements a roll your own batch pattern. This batch pattern is invoked once, runs to completion, and returns an exit status.
The Batchlet interface may be used to implement a Batchlet batch artifact:
package jakarta.batch.api;
/**
*
* A batchlet is type of batch step
* that can be used for any type of
* background processing that does not
* explicitly call for a chunk oriented
* approach.
* <p>
* A well-behaved batchlet responds
* to stop requests by implementing
* the stop method.
*
*/
public interface Batchlet {
/**
* The process method does the work
* of the batchlet. If this method
* throws an exception, the batchlet
* step ends with a batch status of
* FAILED.
* *@return* exit status string
* @throws Exception if an error occurs.
*/
public String process() throws Exception;
/**
* The stop method is invoked by the batch
* runtime as part of JobOperator.stop()
* method processing. This method is invoked
* on a thread other than the thread on which
* the batchlet process method is running.
*
* @throws Exception if an error occurs.
*/
public void stop() throws Exception;
}
package jakarta.batch.api;
/**
* The AbstractBatchlet provides default
* implementations of less commonly implemented methods.
*/
public abstract class AbstractBatchlet implements Batchlet {
/**
* Implement process logic for the Batchlet in this
* method.
*
* *@return* exit status string
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public abstract String process() throws Exception;
/**
* Override this method if the Batchlet will
* end in response to the JobOperator.stop()
* operation.
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void stop() throws Exception {
}
}
|
Tip
|
A well designed batchlet stops gracefully when the JobOperator.stop operation is invoked. See section 11.13 for further information about stop processing. |
9.2. Listeners
Use Listeners to interpose on batch execution.
9.2.1. JobListener Interface
A job listener receives control before and after a job execution runs, and also if an exception is thrown during job processing. The JobListener interface may be used to implement an JobListener batch artifact:
package jakarta.batch.api.listener;
/**
* JobListener intercepts job execution.
*
*/
public interface JobListener {
/**
* The beforeJob method receives control
* before the job execution begins.
* @throws Exception throw if an error occurs.
*/
public void beforeJob() throws Exception;
/**
* The afterJob method receives control
* after the job execution ends.
* @throws Exception throw if an error occurs.
*/
public void afterJob() throws Exception;
}
package jakarta.batch.api.listener;
/**
* The AbstractJobListener provides default
* implementations of less commonly implemented methods.
*/
public abstract class AbstractJobListener implements JobListener
{
/**
* Override this method if the JobListener
* will do something before the job begins.
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void beforeJob() throws Exception {
}
/**
* Override this method if the JobListener
* will do something after the job ends.
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void afterJob() throws Exception {
}
}
9.2.2. StepListener Interface
A step listener can receive control before and after a step runs, and also if an exception is thrown during step processing. The StepListener interface may be used to implement an StepListener batch artifact:
package jakarta.batch.api.listener;
/**
* StepListener intercepts step execution.
*
*/
public interface StepListener {
/**
* The beforeStep method receives control
* before a step execution begins.
* @throws Exception throw if an error occurs.
*/
public void beforeStep() throws Exception;
/**
* The afterStep method receives control
* after a step execution ends.
* @throws Exception throw if an error occurs.
*/
public void afterStep() throws Exception;
}
package jakarta.batch.api.listener;
/**
* The AbstractStepListener provides default
* implementations of less commonly implemented methods.
*/
public abstract class AbstractStepListener implements
StepListener {
/**
* Override this method if the StepListener
* will do something before the step begins.
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void beforeStep() throws Exception {
}
/**
* Override this method if the StepListener
* will do something after the step ends.
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void afterStep() throws Exception {
}
}
9.2.3. ChunkListener Interface
A chunk listener can receive control at the beginning and the end of chunk, and upon an exception thrown back to the runtime implementation. The ChunkListener interface may be used to implement a ChunkListener batch artifact:
package jakarta.batch.api.chunk.listener;
/**
* ChunkListener intercepts chunk processing.
*
*/
public interface ChunkListener {
/**
* The beforeChunk method receives control
* before processing of the next
* chunk begins. This method is invoked
* in the same transaction as the chunk
* processing.
* @throws Exception throw if an error occurs.
*/
public void beforeChunk() throws Exception;
/**
* The onError method receives control
* before the chunk transaction is rolled back.
* Note afterChunk is not invoked in this case.
* @param ex specifies the exception that
* caused the roll back.
* @throws Exception throw if an error occurs.
*/
public void onError(Exception ex) throws Exception;
/**
* The afterChunk method receives control
* after processing of the current
* chunk ends. This method is invoked
* in the same transaction as the chunk
* processing.
* @throws Exception throw if an error occurs.
*/
public void afterChunk() throws Exception;
}
package jakarta.batch.api.chunk.listener;
/**
* The AbstractChunkListener provides default
* implementations of less commonly implemented methods.
*/
public abstract class AbstractChunkListener implements
ChunkListener {
/**
* Override this method if the ChunkListener
* will do something before the chunk begins.
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void beforeChunk() throws Exception {
}
/**
* Override this method if the ChunkListener will do
* something before the chunk transaction is rolled back.
* Note afterChunk is not invoked in this case.
* @param ex specifies the exception that
* caused the roll back.
* @throws Exception (or subclass) throw if an error occurs.
*/
@Override
public void onError(Exception ex) throws Exception {
}
/**
* Override this method if the ChunkListener
* will do something after the chunk ends.
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void afterChunk() throws Exception {
}
}
9.2.4. ItemReadListener Interface
An item read listener can receive control before and after an item is read by an item reader, and also if the reader throws an exception. The ItemReadListener interface may be used to implement an ItemReadListener batch artifact:
package jakarta.batch.api.chunk.listener;
/**
* ItemReadListener intercepts item reader
* processing.
*
*/
public interface ItemReadListener {
/**
* The beforeRead method receives control
* before an item reader is called to read the next item.
* @throws Exception is thrown if an error occurs.
*/
public void beforeRead() throws Exception;
/**
* The afterRead method receives control after an item
* reader reads an item. The method receives the item read as
* an input.
* @param item specifies the item read by the item reader.
* @throws Exception is thrown if an error occurs.
*/
public void afterRead(Object item) throws Exception;
/**
* The onReadError method receives control after an item reader
* throws an exception in the readItem method.
* This method receives the exception as an input.
* @param ex specifies the exception that occurred in the item reader.
* @throws Exception is thrown if an error occurs.
*/
public void onReadError(Exception ex) throws Exception;
}
package jakarta.batch.api.chunk.listener;
/**
* The AbstractItemReadListener provides default
* implementations of less commonly implemented methods.
*/
public abstract class AbstractItemReadListener implements
ItemReadListener {
/**
* Override this method if the ItemReadListener
* will do something before the item is read.
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void beforeRead() throws Exception {
}
/**
* Override this method if the ItemReadListener
* will do something after the item is read.
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void afterRead(Object item) throws Exception {
}
/**
* Override this method if the ItemReadListener
* will do something when the ItemReader readItem
* method throws an exception.
* The default implementation does nothing.
*
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void onReadError(Exception ex) throws Exception {
}
}
9.2.5. ItemProcessListener Interface
An item processor listener can receive control before and after an item is processed by an item processor, and also if the processor throws an exception. The ItemProcessListener interface may be used to implement an ItemProcessListener batch artifact:
package jakarta.batch.api.chunk.listener;
/**
* ItemProcessListener intercepts item processing.
*
*/
public interface ItemProcessListener {
/**
* The beforeProcess method receives control before
* an item processor is called to process the next item.
* The method receives the item to be processed as an input.
* @param item specifies the item about to be processed.
* @throws Exception if an error occurs.
*/
public void beforeProcess(Object item) throws Exception;
/**
* The afterProcess method receives control after an item
* processor processes an item. The method receives the item processed
* and the result item as an input.
* @param item specifies the item processed by the item processor.
* @param result specifies the item to pass to the item writer.
* @throws Exception if an error occurs.
*/
public void afterProcess(Object item, Object result) throws
Exception;
/**
* The onProcessError method receives control after an
* item processor processItem throws an exception. The method
* receives the item sent to the item processor as input.
* @param item specifies the item the processor attempted to process.
* @param ex specifies the exception thrown by the item processor.
* @throws Exception if an error occurs
*/
public void onProcessError(Object item, Exception ex) throws
Exception;
}
package jakarta.batch.api.chunk.listener;
/**
* The AbstractItemProcessListener provides default
* implementations of less commonly implemented methods.
*
*/
public abstract class AbstractItemProcessListener implements
ItemProcessListener {
/**
* Override this method if the ItemProcessListener
* will do something before the item is processed.
* The default implementation does nothing.
*
* @param item specifies the item about to be processed.
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void beforeProcess(Object item) throws Exception {
}
/**
* Override this method if the ItemProcessListener
* will do something after the item is processed.
* The default implementation does nothing.
*
* @param item specifies the item about to be processed.
* @param result specifies the item to pass to the item writer.
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void afterProcess(Object item, Object result) throws
Exception {
}
/**
* Override this method if the ItemProcessListener
* will do something when the ItemProcessor processItem
* method throws an exception.
* The default implementation does nothing.
*
* @param item specifies the item about to be processed.
* @param ex specifies the exception thrown by the item processor.
* @throws Exception (or subclass) if an error occurs.
*/
@Override
public void onProcessError(Object item, Exception ex) throws
Exception {
}
}
9.2.6. ItemWriteListener Interface
A item write listener can receive control before and after an item is written by an item writer, and also if the writer throws an exception. The ItemWriteListener interface may be used to implement an ItemWriteListener batch artifact:
package jakarta.batch.api.chunk.listener;
import java.util.List;
/**
* ItemWriteListener intercepts item writer
* processing.
*
*/
public interface ItemWriteListener {
/**
* The beforeWrite method receives control before
* an item writer is called to write its items. The
* method receives the list of items sent to the item
* writer as an input.
* @param items specifies the items about to be
* written.
* @throws Exception is thrown if an error occurs.
*/
public void beforeWrite(List<Object> items) throws Exception;
/**
* The afterWrite method receives control after an
* item writer writes its items. The method receives the
* list of items sent to the item writer as an input.
* @param items specifies the items written by the item writer.
* @throws Exception is thrown if an error occurs.
*/
public void afterWrite(List<Object> items) throws Exception;
/**
* The onWriteError method receives control after an
* item writer writeItems throws an exception. The method
* receives the list of items sent to the item writer as input.
* @param items specifies the items which the item writer
* attempted to write.
* @param ex specifies the exception thrown by the item
* writer.
* @throws Exception is thrown if an error occurs.
*/
public void onWriteError(List<Object> items, Exception ex) throws
Exception;
}
9.2.7. Skip Listener Interfaces
A skip listener can receive control when a skippable exception is thrown from an item reader, processor, or writer. Three interfaces are provided to implement these listeners:
package jakarta.batch.api.chunk.listener;
/**
* SkipReadListener intercepts skippable
* itemReader exception handling.
*/
public interface SkipReadListener {
/**
* The onSkipReadItem method receives control
* when a skippable exception is thrown from an
* ItemReader readItem method. This method receives the
* exception as an input.
* @param ex specifies the exception thrown by the ItemReader.
* @throws Exception is thrown if an error occurs.
*/
public void onSkipReadItem(Exception ex) throws Exception;
}
package jakarta.batch.api.chunk.listener;
/**
* SkipProcessListener intercepts skippable
* itemProcess exception handling.
*/
public interface SkipProcessListener {
/**
* The onSkipProcessItem method receives control when
* a skippable exception is thrown from an ItemProcess
* processItem method.
* This method receives the exception and the item to process
* as an input.
* @param item specifies the item passed to the ItemProcessor.
* @param ex specifies the exception thrown by the
* ItemProcessor.
* @throws Exception is thrown if an error occurs.
*/
public void onSkipProcessItem(Object item, Exception ex) throws
Exception;
}
package jakarta.batch.api.chunk.listener;
import java.util.List;
/**
* SkipWriteListener intercepts skippable
* itemWriter exception handling.
*/
public interface SkipWriteListener {
/**
* The onSkipWriteItems method receives control when a
* skippable exception is thrown from an ItemWriter
* writeItems method. This
* method receives the exception and the items that were
* skipped as an input.
* @param items specifies the list of item passed to the
* item writer.
* @param ex specifies the exception thrown by the
* ItemWriter.
* @throws Exception is thrown if an error occurs.
*/
public void onSkipWriteItem(List<Object> items, Exception ex)
throws Exception;
}
9.2.8. RetryListener Interface
A retry listener can receive control when a retryable exception is thrown from an item reader, processor, or writer. Three interfaces are provided to implement these listeners:
package jakarta.batch.api.chunk.listener;
/**
* RetryReadListener intercepts retry processing for
* an ItemReader.
*/
public interface RetryReadListener {
/**
* The onRetryReadException method receives control
* when a retryable exception is thrown from an ItemReader
* readItem method.
* This method receives the exception as input. This method
* receives control in the same checkpoint scope as the
* ItemReader. If this method throws a an exception, the job
* ends in the FAILED state.
* @param ex specifies the exception thrown by the item
* reader.
* @throws Exception is thrown if an error occurs.
*/
public void onRetryReadException(Exception ex) throws Exception;
}
package jakarta.batch.api.chunk.listener;
/**
* RetryProcessListener intercepts retry processing for
* an ItemProcessor.
*
*/
public interface RetryProcessListener {
/**
* The onRetryProcessException method receives control
* when a retryable exception is thrown from an ItemProcessor
* processItem method. This method receives the exception and the item
* being processed as inputs. This method receives control in same
* checkpoint scope as the ItemProcessor. If this method
* throws a an exception, the job ends in the FAILED state.
* @param item specifies the item passed to the ItemProcessor.
* @param ex specifies the exception thrown by the ItemProcessor.
* @throws Exception is thrown if an error occurs.
*/
public void onRetryProcessException(Object item, Exception ex)
throws Exception;
}
package jakarta.batch.api.chunk.listener;
import java.util.List;
/**
* RetryWriteListener intercepts retry processing for
* an ItemWriter.
*
*/
public interface RetryWriteListener {
/**
* The onRetryWriteException method receives control when a
* retryable exception is thrown from an ItemWriter writeItems
* method. This method receives the exception and the list of items
* being written as inputs.
* This method receives control in same checkpoint scope as the
* ItemWriter. If this method throws a an exception, the job ends
* in the FAILED state.
* @param items specify the items passed to an item writer.
* @param ex specifies the exception thrown by an item
* writer.
* @throws Exception is thrown if an error occurs.
*/
public void onRetryWriteException(List<Object> items, Exception ex)
throws Exception;
}
9.3. Batch Properties
Batch applications need a way to receive parameters when a job is initiated for execution. Properties can be defined by batch programming model artifacts, then have values passed to them when a job is initiated. Batch properties are string values.
Note batch properties are visible only in the scope in which they are defined (see Section 9.3.2). However batch properties values can be formed from other properties according to Job XML Substitution Rules. See section 8.8 for further information on substitution.
9.3.1. @BatchProperty
The @BatchProperty annotation identifies a class field injection as a batch property. A batch property has a name (name) and default value. The @BatchProperty may be used on a class field for any class identified as a batch programming model artifact -E.g. ItemReader, ItemProcessor, JobListener, etc..
@BatchProperty must be used with the standard @Inject annotation (jakarta.inject.Inject). @BatchProperty is used to assign batch artifact property values from Job XML to the batch artifact itself.
A field annotated with the @BatchProperty annotation must not be static and must not be final.
Note: the batch runtime must ensure @Inject works with @BatchProperty, whether or not the execution environment includes an implementation of JSR 299 or 330. This means the batch properties may always be injected. Whether or not other injections are supported is dependent upon the batch runtime implementation.
Syntax:
package: jakarta.batch.api
@Inject @BatchProperty(name="<property-name>") String <field-name>;
Where:
<property-name> |
is the optional name of this batch property. The default is the Java field name. |
<field-name> |
is the field name of the batch property. |
package jakarta.batch.api;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import jakarta.enterprise.util.Nonbinding;
import jakarta.inject.Qualifier;
/**
* Annotation used by batch artifacts to declare a
* field which is injectable via a JSL-defined value
* (possibly leveraging Job XML substitutions).
*
*/
@Qualifier
@Target({
ElementType._FIELD_, ElementType._METHOD_,
ElementType._PARAMETER_
}
)
@Retention(RetentionPolicy._RUNTIME_)
public @interface BatchProperty {
@Nonbinding
public String name() default "";
}
The value of the annotated field is assigned by the batch runtime if a corresponding property element with a matching name is specified in the JSL in the scope that applies to the batch artifact in question. If the JSL property value resolves to the empty string (either explicitly set to the empty string literal or resolving to an empty string via property substitution – see section 8.8), no assignment is made and the resulting value is undefined by the batch specification. The resulting value might simply be the Java default value, however using various dependency injection technologies may produce different results. The resultant behavior may be defined by the particular dependency injection technology used in the runtime environment and so is outside the scope of this specification. Example:
import jakarta.inject.Inject;
import jakarta.batch.api.BatchProperty;
public class MyItemReaderImpl {
@Inject @BatchProperty String fname;
}
Behavior:
When the batch runtime instantiates the batch artifact (item reader in this example), it assigns the
value of the property with name equal to fname provided in the job XML to the corresponding @BatchProperty field named fname. If no value is defined in JSL, the Java default (null) is assigned or some other default is provided by a particular dependency injection technology.
9.3.2. Scope of property definitions for @BatchProperty Injection
The rules governing the definition of properties for injection via @BatchProperty deserve some extra explanation and an example.
For a given artifact, the only properties that are injectable via @BatchProperty are those which are defined at the level of the artifact itself (i.e. as children of the "properties" element which is in turn a child of the very element defining the artifact: batchlet, reader, listener, etc.).
In particular, just because an artifact definition is contained (at some level of nesting) within a job element and (for most artifacts) within a step element as well, it is NOT the case that the job properties and step properties are themselves injectable into that artifact via @BatchProperty. This is the case even though these job and step properties are available for resolving the artifact-level property definitions via the jobProperties substitution mechanism (see section <IP_ADDRESS>) .
The following example should make this more clear:
<job>
<properties>
<property name="x" value="xVal"/>
...
<step id="step1">
<batchlet ref="MyBatchlet">
<properties>
<property name="y" value="#\{jobProperties['x']}"/>
</properties>
Example Java (MyBatchlet from JSL above):
// WONT WORK! - There is no property 'x' in scope for this injection
@Inject @BatchProperty(name="x");
// WILL WORK – Gets value 'xVal'
@Inject @BatchProperty(name="y");
9.4. Batch Contexts
Context objects are supplied by the batch runtime and provide important functions to a batch application. Contexts provide information about the running batch job, provide a place for a batch job to store interim values, and provide a way for the batch application to communicate important information back to the batch runtime. Contexts can be injected into an application as member variables. There is a context for both job and step. The job context represents the entire job. The step context represents the current step executing within the job.
9.4.1. Batch Contexts
Batch artifact access to batch contexts is by injection using the standard @Inject annotation (jakarta.inject.Inject). A field into which a batch context is injected must not be static and must not be final. E.g.:
@Inject JobContext _jctxt;
@Inject StepContext _sctxt;
The batch runtime is responsible to ensure the correct context object is injected according to the job or step currently executing.
Note: the batch runtime must ensure @Inject works with JobContext and StepContext, whether or not the execution environment includes an implementation of JSR 299 or 330. This means the batch contexts may always be injected. Whether or not other injections are supported is dependent upon the batch runtime implementation. See section 10.9.1 for definition of JobContext class. See section 10.9.2 for definition of StepContext class.
<IP_ADDRESS>. Batch Context Lifecycle and Scope
A batch context has thread affinity and is visible only to the batch artifacts executing on that particular thread. A batch context injected field may be null when out of scope. Each context type has a distinct scope and lifecycle as follows:
-
JobContext
There is one JobContext per job execution. It exists for the life of a job. There is a distinct JobContext for each sub-thread of a parallel execution (e.g. partitioned step).
-
StepContext
There is one StepContext per step execution. It exists for the life of the step. For a partitioned step, there is one StepContext for the parent step/thread; there is a distinct StepContext for each sub-thread and each StepContext has its own distinct persistent user data for each sub-thread.
9.5. Parallelization
Batch jobs may be configured to run some of their steps in parallel. There are two supported parallelization models:
-
Partitioned:
In the partitioned model, a step is configured to run as multiple instances across multiple threads. Each thread runs the same step or flow. This model is logically equivalent to launching multiple instances of the same step. It is intended that each partition processes a different range of the input items.
The partitioned model includes several optional batch artifacts to enable finer control over parallel processing:
-
PartitionMapper provides a programmatic means for calculating the number of partitions and unique properties for each.
-
PartitionReducer provides a unit of work demarcation around partition processing.
-
PartitionCollector provides a means for merging interrim results from individual partitions.
-
PartitionAnalyzer provides a means to gather interrim and final results from individual partitions for single point of control processing and decision making.
-
-
Concurrent:
In the concurrent model, the flows defined by a split are configured to run concurrently on multiple threads, one flow per thread.
9.5.1. PartitionMapper Interface
A partition mapper receives control at the start of a partitioned execution. The partition mapper is responsible to provide unique batch properties for each partition. The PartitionMapper interface may be used to implement a PartitionMapper batch artifact:
package jakarta.batch.api.partition;
import jakarta.batch.api.partition.PartitionPlan;
/**
* PartitionMapper receives control at the start of a partitioned
* execution. A PartitionMapper is responsible to provide unique
* batch properties for each partition.
*
*/
public interface PartitionMapper {
/**
* The mapPartitions method that receives control at the
* start of partitioned step processing. The method
* returns a PartitionPlan, which specifies the batch properties
* for each partition.
* *@return* partition plan for a partitioned step.
* @throws Exception is thrown if an error occurs.
*/
public PartitionPlan mapPartitions( ) throws Exception;
}
See section 10.9.4 for details on the PartitionPlan result value type.
The PartitionMapper, when defined, is invoked upon every execution, including restarted executions. For a full discussion of the behavior on restart, including how to override particular details of the PartitionPlan built by the previous execution, see section 10.8.5.
9.5.2. PartitionReducer Interface
A partition reducer provides a unit of work demarcation across partitions. It is not a JTA transaction; no resources are enlisted. Rather, it provides transactional flow semantics to facilitate finalizing merge or compensation logic. The PartitionReducer interface may be used to implement an PartitionReducer batch artifact:
package jakarta.batch.api.partition;
/**
* PartitionReducer provides unit of work demarcation across
* partitions. It is not a JTA transaction; no resources are
* enlisted. Rather, it provides transactional flow semantics
* to facilitate finalizing merge or compensation logic.
*
*/
public interface PartitionReducer {
public *enum* PartitionStatus {
COMMIT_, _ROLLBACK
}
/**
* The beginPartitionedStep method receives
* control at the start of partition processing.
* It receives control before the PartitionMapper
* is invoked and before any partitions are started.
* @throws Exception is thrown if an error occurs.
*/
public void beginPartitionedStep() throws Exception;
/**
* The beforePartitionedStepCompletion method
* receives control at the end of partitioned
* step processing. It receives control after all
* partitions have completed. It does not receive
* control if the PartitionReducer is rolling back.
* @throws Exception is thrown if an error occurs.
*/
public void beforePartitionedStepCompletion() throws Exception;
/**
* The rollbackPartitionedStep method receives
* control if the runtime is rolling back a partitioned
* step. Any partition threads still running are
* allowed to complete before this method is invoked. This method
* receives control if any of the following conditions
* are true:
* <p>
* <ol>
* <li>One or more partitions end with a Batch Status of
* STOPPED or FAILED.</li>
* <li>Any of the following partitioned step callbacks
* throw an exception:</li>
* <ol>
* <li>PartitionMapper</li>
* <li>PartitionReducer</li>
* <li>PartitionCollector</li>
* <li>PartitionAnalyzer</li>
* </ol>
* <li>A job with partitioned steps is restarted.</li>
* </ol>
* @throws Exception is thrown if an error occurs.
*/
public void rollbackPartitionedStep() throws Exception;
/**
* The afterPartitionedStepCompletion method receives control
* at the end of a partition processing. It receives a status
* value that identifies the outcome of the partition processing.
* The status string value is either "COMMIT" or "ROLLBACK".
* @param status specifies the outcome of the partitioned step. Values
* are "COMMIT" or "ROLLBACK".
* @throws Exception is thrown if an error occurs.
*/
public void afterPartitionedStepCompletion(PartitionStatus status)
throws Exception;
}
package jakarta.batch.api.partition;
/**
* The AbstractPartitionReducer provides default
* implementations of less commonly implemented methods.
*/
public abstract class AbstractPartitionReducer implements
PartitionReducer {
/**
* Override this method to take action before
* partitioned step processing begins.
*
* @throws Exception is thrown if an error occurs.
*/
@Override
public void beginPartitionedStep() throws Exception {
}
/**
* Override this method to take action before
* normal partitioned step processing ends.
*
* @throws Exception is thrown if an error occurs.
*/
@Override
public void beforePartitionedStepCompletion() throws Exception {
}
/**
* Override this method to take action when a
* partitioned step is rolling back.
*
* @throws Exception is thrown if an error occurs.
*/
@Override
public void rollbackPartitionedStep() throws Exception {
}
/**
* Override this method to take action after
* partitioned step processing ends.
*
* @param status specifies the outcome of the partitioned step.
* Values are "COMMIT" or "ROLLBACK".
* @throws Exception is thrown if an error occurs.
*/
@Override
public void afterPartitionedStepCompletion(PartitionStatus status)
throws Exception {
}
}
9.5.3. PartitionCollector Interface
A partition collector provides a way to send data from individual partitions to a single point of control running on the parent thread. The PartitionAnalyzer is used to receive and process this data. See section 9.5.4 for further information about the PartitionAnalyzer. The PartitionCollector interface may be used to implement an PartitionCollector batch artifact:
package jakarta.batch.api.partition;
import java.io.Serializable;
/**