paulwong

SPRING BATCH 错误通知机制

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



posted on 2012-11-17 21:42 paulwong 阅读(4615) 评论(1)  编辑  收藏 所属分类: SRPING BATCH

Feedback

# re: SPRING BATCH 错误通知机制 2013-08-16 09:27 paulwong

@清风
是SPRING BATCH自带的ADMIN CONSOLE?那是要人工去查看的,这个可以实现自动通知机制,如发邮件等。  回复  更多评论   



只有注册用户登录后才能发表评论。


网站导航: