运行SPRING BATCH JOB 的时候,有可能出错,如果能有相关的错误处理机制,则这些错误就能及时得到处理。
SPRING BATCH 提供了监听器,可配置在JOB执行完后,或执行JOB前,要执行的方法。
JOB的定义及BEAN的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd">
<batch:job id="restartHelloWorldJob">
<batch:step id="restartStep1" next="restartStep2">
<batch:tasklet ref="helloWorldTasklet"></batch:tasklet>
</batch:step>
<batch:step id="restartStep2" next="restartStep3">
<batch:tasklet ref="helloWorldTwoTasklet"></batch:tasklet>
</batch:step>
<batch:step id="restartStep3" >
<batch:tasklet ref="helloWorldThreeTasklet"></batch:tasklet>
</batch:step>
<batch:listeners>
<batch:listener ref="monitoringJobListener"></batch:listener>
</batch:listeners>
</batch:job>
<bean id="helloWorldTasklet" class="com.paul.batch.tasklet.HelloWorldTasklet"></bean>
<bean id="helloWorldTwoTasklet" class="com.paul.batch.tasklet.HelloWorldTwoTasklet"></bean>
<bean id="helloWorldThreeTasklet" class="com.paul.batch.tasklet.HelloWorldThreeTasklet"></bean>
<!-- <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value=""></property>
</bean>
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="batch-notifier@example.com" />
<property name="to" value=""></property>
</bean>
<bean id="emailMonitoringNotifier" class="com.paul.batch.notifier.EmailMonitoringNotifier">
<property name="mailSender" ref="mailSender" />
<property name="templateMessage" ref="templateMessage" />
</bean> -->
<bean id="logMonitoringNotifier" class="com.paul.batch.notifier.LogMonitoringNotifier">
</bean>
<bean id="monitoringJobListener" class="com.paul.batch.listener.MonitoringExecutionListener">
<property name="monitoringNotifier" ref="logMonitoringNotifier"></property>
</bean>
</beans>
监听器MonitoringExecutionListener:
package com.paul.batch.listener;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.annotation.AfterJob;
import org.springframework.batch.core.annotation.BeforeJob;
import com.paul.batch.notifier.BatchMonitoringNotifier;
public class MonitoringExecutionListener {
private BatchMonitoringNotifier monitoringNotifier;
@BeforeJob
public void executeBeforeJob(JobExecution jobExecution) {
// Do nothing
}
@AfterJob
public void executeAfterJob(JobExecution jobExecution) {
if (jobExecution.getStatus() == BatchStatus.FAILED) {
// Notify when job fails
monitoringNotifier.notify(jobExecution);
}
}
public void setMonitoringNotifier(BatchMonitoringNotifier monitoringNotifier) {
this.monitoringNotifier = monitoringNotifier;
}
}
BatchMonitoringNotifier接口
package com.paul.batch.notifier;
import org.springframework.batch.core.JobExecution;
public interface BatchMonitoringNotifier {
void notify(JobExecution jobExecution);
}
LogMonitoringNotifier实现
package com.paul.batch.notifier;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.List;
import org.springframework.batch.core.JobExecution;
public class LogMonitoringNotifier implements BatchMonitoringNotifier {
private String formatExceptionMessage(Throwable exception) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
exception.printStackTrace(new PrintStream(baos));
return baos.toString();
}
private String createMessageContent(JobExecution jobExecution) {
List<Throwable> exceptions = jobExecution.getAllFailureExceptions();
StringBuilder content = new StringBuilder();
content.append("Job execution #");
content.append(jobExecution.getId());
content.append(" of job instance #");
content.append(jobExecution.getJobInstance().getId());
content.append(" failed with following exceptions:");
for (Throwable exception : exceptions) {
content.append("");
content.append(formatExceptionMessage(exception));
}
return content.toString();
}
public void notify(JobExecution jobExecution) {
String content = createMessageContent(jobExecution);
System.out.println(content);
}
}
EmailMonitoringNotifier实现
package com.paul.batch.notifier;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.List;
import org.springframework.batch.core.JobExecution;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
public class EmailMonitoringNotifier implements BatchMonitoringNotifier {
private MailSender mailSender;
private SimpleMailMessage templateMessage;
private String formatExceptionMessage(Throwable exception) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
exception.printStackTrace(new PrintStream(baos));
return baos.toString();
}
private String createMessageContent(JobExecution jobExecution) {
List<Throwable> exceptions = jobExecution.getFailureExceptions();
StringBuilder content = new StringBuilder();
content.append("Job execution #");
content.append(jobExecution.getId());
content.append(" of job instance #");
content.append(jobExecution.getJobInstance().getId());
content.append(" failed with following exceptions:");
for (Throwable exception : exceptions) {
content.append("");
content.append(formatExceptionMessage(exception));
}
return content.toString();
}
public void notify(JobExecution jobExecution) {
SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
msg.setTo("batch-administrator@example.com");
String content = createMessageContent(jobExecution);
msg.setText(content);
try {
mailSender.send(msg);
} catch (MailException ex) {
}
}
public MailSender getMailSender() {
return mailSender;
}
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
public SimpleMailMessage getTemplateMessage() {
return templateMessage;
}
public void setTemplateMessage(SimpleMailMessage templateMessage) {
this.templateMessage = templateMessage;
}
}
MAVEN pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-simple-cli</artifactId>
<version>2.1.9.RELEASE</version>
<packaging>jar</packaging>
<name>Commandline</name>
<url>http://www.springframework.org/spring-batch/archetypes/simple-cli-archetype</url>
<description>This project is a minimal command line batch sample from
Spring Batch. Once installed you can use "mvn exec:java" to
see the job run; or if you ship the lib directory you can put
the project jar on the classpath and run the
CommandLineJobRunner directly or with "java -jar launch-context.xml job1".</description>
<properties>
<maven.test.failure.ignore>true</maven.test.failure.ignore>
<spring.framework.version>3.0.5.RELEASE</spring.framework.version>
<spring.batch.version>2.1.9.RELEASE</spring.batch.version>
<dependency.locations.enabled>false</dependency.locations.enabled>
<spring.integration.version>2.0.6.RELEASE</spring.integration.version>
</properties>
<profiles>
<profile>
<id>strict</id>
<properties>
<maven.test.failure.ignore>false</maven.test.failure.ignore>
</properties>
</profile>
<profile>
<id>staging</id>
<distributionManagement>
<repository>
<id>staging</id>
<url>file:///${user.dir}/target/staging</url>
</repository>
<snapshotRepository>
<id>staging</id>
<url>file:///${user.dir}/target/staging</url>
</snapshotRepository>
</distributionManagement>
</profile>
<profile>
<id>bootstrap</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<pluginRepositories>
<!-- <pluginRepository>
<id>Codehaus</id>
<url>http://repository.codehaus.org/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository> -->
<pluginRepository>
<id>com.springsource.repository.bundles.release</id>
<name> SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases</name>
<url>http://repository.springsource.com/maven/bundles/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
<version>${spring.batch.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-infrastructure</artifactId>
<version>${spring.batch.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<version>${spring.batch.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-integration</artifactId>
<version>1.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-file</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jdbc</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.framework.version}</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>org.springframework.build.aws</groupId>
<artifactId>org.springframework.build.aws.maven</artifactId>
<version>3.0.0.RELEASE</version>
</extension>
</extensions>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<inherited>false</inherited>
<configuration>
<descriptorRefs>
<descriptorRef>project</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>com.springsource.bundlor</groupId>
<artifactId>com.springsource.bundlor.maven</artifactId>
<versionRange>[1.0,)</versionRange>
<goals>
<goal>bundlor</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<versionRange>[1.0,)</versionRange>
<goals>
<goal>copy-dependencies</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>com.springsource.bundlor</groupId>
<artifactId>com.springsource.bundlor.maven</artifactId>
<version>1.0.0.RELEASE</version>
<executions>
<execution>
<id>bundlor-transform</id>
<phase>compile</phase>
<goals>
<goal>bundlor</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.3</version>
<configuration>
<includes>
<include>**/*Tests.java</include>
</includes>
<excludes>
<exclude>**/Abstract*.java</exclude>
</excludes>
<junitArtifactName>junit:junit</junitArtifactName>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<mainClass>org.springframework.batch.core.launch.support.CommandLineJobRunner</mainClass>
<arguments>
<argument>classpath:/launch-context.xml</argument>
<argument>job1</argument>
</arguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3</version>
<configuration>
<archive>
<index>false</index>
<manifest>
<mainClass>org.springframework.batch.core.launch.support.CommandLineJobRunner</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<distributionManagement>
<downloadUrl>http://www.springframework.org/download</downloadUrl>
<site>
<id>staging</id>
<url>file:///${user.dir}/target/staging/org.springframework.batch.archetype/${pom.artifactId}</url>
</site>
<repository>
<id>spring-release</id>
<name>Spring Release Repository</name>
<url>file:///${user.dir}/target/staging/release</url>
</repository>
<snapshotRepository>
<id>spring-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>file:///${user.dir}/target/staging/snapshot</url>
</snapshotRepository>
</distributionManagement>
</project>