Summary: This document contains information about the extension providing Spring Batch and JSR-352 support for JEE.
Important:
- Before installing the new extension providing Spring Batch and JSR-352 support for JEE, you must uninstall first com.castsoftware.uc.springbatch if present. The two extensions cannot be used simultaneously. Also, the migration is not supported between the two.
- In order to avoid duplication and confusion, when using the Spring Batch extension, any Spring Batch Job and Spring Batch Step objects created by the JEE analyzer will be deleted from the Analysis schema at application level and replaced with corresponding objects created by the Batch extension. You should therefore expect a small impact on existing analysis results in terms of the number of added/deleted objects.
Extension ID
com.castsoftware.springbatch
What's New?
Please see Batch Analyzer - 3.0 - Release Notes for more information.
Description
In what situation should you install this extension?
The main goal of this extension is to analyze a batch application and enable linking between spring batch objects and between Java objects and Batch objects. If a JEE application contains source code which uses Spring Batch or JSR-352 frameworks and you want to view these objects and also the links with other objects, then you should install this extension.
Features of Spring Batch Framework
Spring Batch is a framework designed to develop robust batch applications. It is not a scheduling framework, but it can work in conjuction with a scheduler (take the example of Quartz).
Batch procesing can be described as a form of reading in large amounts of data, process it and writing the result out. The architecture of Spring Batch contains three major high-level components: Application, Core, and Infrastructure. The Application contains all batch jobs and custom code written using Spring Batch. The Batch Core contains the core runtime classes necessary to launch and control a batch job. It includes implementations of JobLauncher, Job and Step. Both Application and Core are built on top of a common Infrastructure which contains readers, writers, services (ItemReader, ItemWriter, ItemProcessor).
A Job is an entity which encapsulates an entire batch process. A Job may be configured using either an XML configuration file or a Java-based configuration file. The Spring Batch extension handles the XML configuration file only.
The Spring Batch extension enables linking between:
- Java objects running Batch Jobs and the corresponding Batch Jobs
- Batch objects and methods controlling their execution
- Batch objects and methods defined in batch artifacts
Configuration of a Job
The batch process is encapsulated in a JOB. A JOB consists of multiple STEPS. Each STEP has only one READER-PROCESSOR-WRITER sequence. A JOB is executed by a JobLauncher. Metadata about configured and executed jobs is encapsulated in JobRepository. Each JOB is associated with JobInstances. A JobInstance is defined uniquely by its JobParameters (used to start a batch job). Each run of a JobInstance is referred to as a JobExecution. Each STEP has an individual StepExecution.
<import resource="../config/context.xml" /> <import resource="../config/database.xml" /> <batch:job id="helloWorldJob"> //helloWorldJob Job consisting of steps,steps having chunk reader, writer, processor <batch:step id="step1"> <batch:tasklet> <batch:chunk reader="cvsFileItemReader" writer="xmlItemWriter" processor="itemProcessor" commit-interval="10"> //reader writer and processor dependency </batch:chunk> </batch:tasklet> </batch:step> </batch:job> ... <bean id="cvsFileItemReader" class="ExampleItemReader" scope="step"/> <bean id="xmlItemWriter" class="ExampleItemWriter" scope="step"/> <bean id="itemProcessor" class="ExampleItemProcessor" scope="step"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> //joblauncher having dependency of JobRepository <property name="jobRepository" ref="jobRepository" /> </bean> <bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="transactionManager" ref="transactionManager" /> <property name="databaseType" value="mysql" /> </bean> <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
There are two approaches to build a STEP.
Tasklet based
The execution of the Spring Batch Step is invoked in classes which inherit from Tasklet class. The execute() method is defined inside the class and each call to the Tasklet is wrapped in a Transaction. Tasklet implementors might call a stored procedure, a script, or a simple SQL update statement. We create links between the execute() methods and the STEP. To create a TaskletStep, the 'ref' attribute of the <tasklet/> element should reference a bean that defines a Tasklet. No <chunk/> element should be used within the <tasklet/>.
<import resource="../config/context.xml" /> <import resource="../config/database.xml" /> <batch:job id="helloWorldJob"> //helloWorldJob Job consisting of steps,steps having tasklet <batch:step id="step1"> <batch:tasklet ref="exampleTasklet"> </batch:tasklet> </batch:step> </batch:job> ... <bean id="exampleTasklet" class="ExampleTasklet "scope="step"> ... </bean>
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.step.tasklet.Tasklet; public class ExampleTasklet implements Tasklet{ @Override public ExitStatus execute(){ ... } }
Chunk-oriented processing
Consists reading the data sequentially and creating “chunks” that will be written out within a transaction boundary. Each individual item is read in from an ItemReader, handed to an ItemProcessor, and once the number of items read equals the commit interval (if specified), the entire chunk is written out via the ItemWriter, and then the transaction is committed.
method | interface |
---|---|
read() | org.springframework.batch.item.ItemReader org.springframework.batch.item.ItemStreamReader |
process() | org.springframework.batch.item.ItemProcessor org.springframework.batch.item.support.ScriptItemProcessor |
write() | org.springframework.batch.item.ItemWriter org.springframework.batch.item.ItemStreamWriter |
We create links between the STEP and the methods read(), process() and write().
import org.springframework.batch.item.ItemStreamReader; import org.springframework.beans.factory.annotation.Autowired; public class ExampleItemReader implements ItemReader<Class1>{ @Override public Class1 read() throws Exception{ ... } }
import org.springframework.batch.item.ItemProcessor; import org.springframework.beans.factory.annotation.Autowired; public class ExampleItemProcessor implements ItemProcessor<Class1, Class2>{ @Override public Class2 process(Class1 arg) throws Exception{ ... } }
import org.springframework.batch.item.ItemWriter; import org.springframework.beans.factory.annotation.Autowired; public class ExampleItemWriter implements ItemWriter<Class1>{ @Override public void write(List<? extends Class1> items) throws Exception{ ... } }
Running a Job
A container is responsible for instantiating, configuring and assembling the beans. There are 2 types of containers: BeanFactory and ApplicationContext. ApplicationContext is a superset of BeanFactory. You can find here the difference between them. ApplicationContext is an interface in the org.springframework.context package and it has several implementations, and the ClassPathXmlApplicationContext is one of these. getBean() is a method from the BeanFactory interface responsible for retrieving a bean instance from the Spring container. The getBean() method is most frequently accessed through the ApplicationContext. ApplicationContext provides the JobLauncher to run the JOB.
import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecutionException; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParametersBuilder; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String [] args){ String[] springConfig = {"spring/batch/jobs/job.xml" }; //Load the Job.xml file,this Job.xml has dependency on JobLauncher // which will load the Repository ApplicationContext context = new ClassPathXmlApplicationContext(springConfig); JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher"); //get the JobLauncher object Job job = (Job) context.getBean("helloWorldJob"); //get the Job Object try { JobExecution execution = jobLauncher.run(job, new JobParameters()); //start the job by calling the run method System.out.println("Exit Status : " + execution.getStatus()); } catch (Exception e) { e.printStackTrace(); } } }
Listeners in Spring Batch
Spring Batch framework uses listeners to provide progress information on Spring Batch Jobs and Spring Batch Steps. These are called event-driven listeners. The most commonly used listeners are: JobExecutionListener, StepListener and ChunckListener.
Exemple of code for job listener declaration in xml file:
<import resource="../config/context.xml" /> <import resource="../config/database.xml" /> <batch:job id="helloWorldJob"> //helloWorldJob Job consisting of steps,steps having tasklet <batch:step id="step1"> <batch:tasklet ref="exampleTasklet"> </batch:tasklet> </batch:step> <listeners> <listener ref="jobListener"></listener> </listeners> </batch:job> ... <bean id="exampleTasklet" class="ExampleTasklet "scope="step"> ... </bean> <beans id="jobListener" class="ExampleListenerJob"> ... </bean>
Exemple of code for step listener declaration in xml file:
<import resource="../config/context.xml" /> <import resource="../config/database.xml" /> <batch:job id="helloWorldJob"> //helloWorldJob Job consisting of steps,steps having tasklet <batch:step id="step1"> <batch:tasklet ref="exampleTasklet"> </batch:tasklet> <listeners> <listener ref="stepListener"></listener> </listeners> </batch:step> </batch:job> ... <bean id="exampleTasklet" class="ExampleTasklet "scope="step"> ... </bean> <beans id="stepListener" class="ExampleListenerStep"> ... </bean>
In the case of JOBS, the class responsible for supervising the execution is 'org.springframework.batch.core.JobExecutionListener'. Two methods allow to see the status of the JOB: beforeJob() and afterJob().
import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecutionListener; public class ExampleJobExecutionListener implements JobExecutionListener { @Override public void beforeJob(JobExecution jobExecution) { ... } @Override public void afterJob(JobExecution jobExecution) { ... } }
There might be cases where the classes containing the methods do not inherit from JobExecutionListener class. In this case, the annotations @BeforeJob and @AfterJob are used. Links between these methods and the corresponding JOBS are created with Spring Batch extension.
In the case of the STEPS, the classes responsible for supervising the execution are: 'org.springframework.batch.core.StepExecutionListener', 'org.springframework.batch.core.ItemReadListener', 'org.springframework.batch.core.ItemWriteListener', 'org.springframework.batch.core.ItemProcessListener', 'org.springframework.batch.core.ChunkListener'. The corresponding methods are: 'afterStep()', 'beforeStep()', 'beforeWrite()', 'afterWrite()', 'onWriteError()', 'beforeProcess()', 'afterProcess()', 'onProcessError()', 'beforeRead()', 'afterRead()', 'onReadError()', 'beforeChunk()', 'afterChunk()', 'afterChunkError()'. Here also there are cases where annotations like @BeforeStep and @AfterStep are used.
Links between these methods and the corresponding STEPS are created in the extension for Spring Batch framework.
Access to databases
Item beans provide access to databases. Classes which allow database access are org.springframework.batch.item.database.JdbcCursorItemReader and org.springframework.batch.item.database.JdbcCursorItemWriter. The access is possible via Spring Beans. In this extension links are created between Batch Steps and Spring Beans only if the beans have sql properties and are linked to tables.
<import resource="../config/context.xml" /> <import resource="../config/database.xml" /> <batch:job id="helloWorldJob"> //helloWorldJob Job consisting of steps,steps having chunk reader, writer, processor <batch:step id="step1"> <batch:tasklet> <batch:chunk reader="infoItemReader" writer="infoItemWriter" processor="itemProcessor" commit-interval="10"> //reader writer and processor dependency </batch:chunk> </batch:tasklet> </batch:step> </batch:job> ... <bean id="infoItemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step"> <property name="sql" value="SELECT * FROM INFORMATIONS"/> </bean>
Features of JSR-352 Framework
JSR-352 is a framework similar to Spring Batch. Just as mentioned in the documentation above, it's functionalities are based on jobs, steps, readers, writers, processors, listeners.
The first difference between the two frameworks is the job execution, as illustrated in the code example below. The interface javax.batch.operations.JobOperator
allows the execution of the job. This implementation is loaded via thejavax.batch.runtime.BatchRuntime
interface.
import javax.batch.operations.JobOperator; import javax.batch.runtime.BatchRuntime; import java.util.Properties; public class Main { public static void main(String [] args){ JobOperator operator = BatchRuntime.getJobOperator(); jobOperator.start("helloWorldJob", new Properties()); }
Another difference is the structure of the xml file and the tag names. The "tasklet" tag is called "batchlet" in the JSR-352 framework. As for readers, writers and processors, which were attibutes of "chunk" tag in Spring Batch framework, they become individual tags under the "chunk" tag.
<job id="helloWorldJob"> //helloWorldJob Job consisting of steps,steps having chunk reader, writer, processor <step id="step1"> <chunk> <reader="cvsFileItemReader"> <writer="xmlItemWriter"> <processor="itemProcessor" commit-interval="10"> </chunk> </step> </job>
The classes we support in JSR-352 framework are:
method | interface |
---|---|
readItem() | javax.batch.api.chunk.AbstractItemReader |
processItem() | javax.batch.api.chunk.ItemProcessor |
writeItem() | javax.batch.api.chunk.AbstractItemWriter |
process(), stop() | javax.batch.api.AbstractBatchlet javax.batch.api.Batchlet |
beforeJob(), afterJob() | javax.batch.api.listener.JobListener |
beforeStep(), afterStep() | javax.batch.api.listener.StepListener |
Links between these methods and the corresponding JOBS and STEPS are created in the extension for JSR-352 framework.
CAST AIP compatibility
CAST AIP release | Supported |
---|---|
8.3.x | |
8.2.x |
Prerequisites
An installation of any compatible release of CAST AIP (see table above) |
Dependencies with other extensions
Some CAST extensions require the presence of other CAST extensions in order to function correctly. The Spring Batch extension requires that the following other CAST extensions are also installed:
- CAST AIP Internal extension (internal technical extension)
Download and installation instructions
Please see:
The latest release status of this extension can be seen when downloading it from the CAST Extend server.
What results can you expect?
Once the analysis/snapshot generation has completed, you can visualize the results in the usual manner:
In the CAST Management Studio:
In CAST Enlighten:
- Spring Batch framework
- JSR-352 framework
Objects
The following objects are displayed in CAST Enlighten:
Icon | Object Type |
---|---|
Batch Job | |
Batch Step |
In order to avoid duplication and confusion, when using the Spring Batch extension, any Spring Batch Job and Spring Batch Step objects created by the JEE analyzer will be deleted from the Analysis schema at application level.
Links
The following call links are added:
- Between Batch Jobs and Batch Steps
- Between Batch Jobs and beforeJob() and afterJob() methods defined in JobExecutionListener classes
- Between the methods calling jobs and Batch Jobs
- Between Batch Steps and other Batch Steps
- Between Batch Steps and execute() methods defined in Tasklet classes
- Between Batch Steps and process() methods defined in ItemProcessor, ItemScriptItemProcessor classes
- Between Batch Steps and read(), open(), update(), close() methods defined in ItemReader and ItemStreamReader classes
- Between Batch Steps and write(), open(), update(), close() methods defined in ItemWriter and ItemStreamWriter classes
- Between Batch Steps and beforeStep(), afterStep(), beforeWrite(), afterWrite(), onWriteError(), beforeProcess(), afterProcess(), onProcessError(), beforeRead(), afterRead(), onReadError(), beforeChunk(), afterChunk(), afterChunkError() methods defined in StepExecutionListener, ItemWriteListener, ItemProcessListener, ItemReadListener, ChunkListener classes
- Between Batch Steps and Spring Beans if beans have sql properties and Spring Beans are linked to tables
Known limitations
- The Spring Batch extension is limited to xml based job configuration.
- Jobs created through Java Api JobExecution not yet supported
- When using the Spring Batch extension, any Spring Batch Job and Spring Batch Step objects created by the JEE analyzer will be deleted from the Analysis schema at application level.
- Support of Java Beans containing SQL queries in Spring Batch framework : links between Batch Step and Spring Bean containing queries are added if Spring Bean are linked to tables.
- Links between Batch Step and Spring Bean are not supported for JSR-352 framework.