【问题标题】:Spring Batch hangs with no outputSpring Batch 挂起,没有输出
【发布时间】:2016-05-25 15:16:44
【问题描述】:

我有一个从 Spring 引导应用程序启动的 Spring Batch 作业,如下所示:

主要:

@SpringBootApplication
@ImportResource("jobApplicationContext.xml")
public class BatchJobRunner {

    public static void main(String[] args) {
        SpringApplication.run(BatchJobRunner.class, args);
    }

}

在我的工作申请环境中,我有以下项目:

<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <context:property-placeholder location="classpath:*.properties"/>

    <bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry"/>
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>

    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository" />
    </bean>

    <batch:job id="myJob" job-repository="jobRepository">
        <batch:split id="main" task-executor="simpleAsyncTaskExecutor" next="step3">
            <batch:flow>
                <batch:step id="flow1">
                    <!-- definition -->
                </batch:step>
            </batch:flow>
            <batch:flow>
            <batch:step id="flow2">
                <!-- definition -->
            </batch:step>
            </batch:flow>
        </batch:split>
        <batch:step id="step3">
            <batch:tasklet ref="someTasklet"/>
        </batch:step>
    </batch:job>
</beans>

最后,我只是这样运行它:

java -jar my-module.jar

作业开始但是:

  • 它不会打印出任何东西。这是我的 log4j.properties:

    log4j.rootLogger=INFO, stdout
    log4j.logger.org.springframework.batch=INFO
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target=System.out
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
    
  • 作业最后挂起。我在 step3 中放了一个 Sys.out.print 并且它确实打印了,但是 spring boot 应用程序一直在运行并且永远不会退出。我还尝试添加@AfterJobSystem.exit(..),但也没有用。

我正在使用 Spring f/w 4.1.8、spring boot 1.2.8 和 spring batch 3.0.6(我无法升级我的 spring-core,因为某些依赖项使用该版本)。

知道我做错了什么吗?

编辑:

看起来 beforeJob 和 afterJob 监听器根本没有触发。

【问题讨论】:

  • 它挂了哪一步..你是从数据库还是其他地方读取..
  • @surya 如果您查看我的代码 sn-p,我正在使用内存注册表。但我很确定它不会停滞不前。当我在 Spring XD 中运行它时,我能够运行相同的作业。

标签: java spring spring-boot spring-batch


【解决方案1】:

ClassCastExeption 可能是 Spring 不同绑定的结果(xml 早期和 java 晚期)。尝试在 java 中完全配置您的批处理。结果可能如下所示(这是存储在 DB 中的存储库,inmemory 存储库应该看起来相似):

@Configuration
@EnableBatchProcessing
@ComponentScan("my.batch.*")
@ImportResource("classpath:batch-config.xml")
@PropertySource(value = "classpath:batch.properties")
public class BatchConfiguration implements BatchConfigurer {

@Autowired
private DataSource dataSource;
private PlatformTransactionManager transactionManager;
private JobRepository jobRepository;
private JobLauncher jobLauncher;
private JobExplorer jobExplorer;

@Override
public JobRepository getJobRepository() throws Exception {
    return jobRepository;
}

@Override
public PlatformTransactionManager getTransactionManager() throws Exception {
    return transactionManager;
}

@Override
public JobLauncher getJobLauncher() throws Exception {
    return jobLauncher;
}

@Override
public JobExplorer getJobExplorer() throws Exception {
    return jobExplorer;
}

@PostConstruct
public void initialize() {
    try {
        transactionManager = new DataSourceTransactionManager(dataSource);
        jobRepository = createJobRepository();

        jobExplorer = createJobExplorer();
        jobLauncher = createJobLauncher();
    } catch (Exception ex) {
        throw  new BatchConfigurationException(ex);
    }
}

private JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean repoFactory = new JobRepositoryFactoryBean();

    repoFactory.setDataSource(dataSource);
    repoFactory.setTransactionManager(transactionManager);
    repoFactory.setTablePrefix(PREFIX);

    repoFactory.afterPropertiesSet();

    return repoFactory.getObject();
}

private JobExplorer createJobExplorer() throws Exception {
    JobExplorerFactoryBean explorerFactory = new JobExplorerFactoryBean();

    explorerFactory.setDataSource(dataSource);
    explorerFactory.setTablePrefix(PREFIX);

    explorerFactory.afterPropertiesSet();

    return explorerFactory.getObject();
}

private JobLauncher createJobLauncher() throws Exception {
    SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
    jobLauncher.setJobRepository(jobRepository);
    jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());

    jobLauncher.afterPropertiesSet();

    return jobLauncher;
}
}

【讨论】:

  • 首先,非常感谢您的详细解答!我尝试了您的解决方案,并尝试在我的 XML 中定义一个 ,这两个都给了我这个错误: org.springframework.batch.core.repository.JobExecutionAlreadyRunningException: A job execution for this job is already running 我明白我将不得不向作业传递一个随机参数来解决这个问题。你知道我该怎么做吗?
  • 好的,所以我从 Spring Boot 的 main() 中手动调用了该作业,现在至少我的作业没有挂起(耶!)。现在我只需要修复作业的日志记录级别,并找出为什么即使我的日志级别设置为信息也没有打印任何内容,并且我的所有记录器调用都打印为信息。
  • 经过一番挖掘,我的 jar 中缺少 slf4j-simple,这解决了我的日志记录问题。除了 slf4j-api 之外,这也是必需的。谢谢你的回答,我希望你有一个美好的一周。
  • 给了@rell 一个点,以激励 SayakBanerjee 使用 Java 配置,我相信这从 servlet 2.5 开始就可以实现。由于 2011 年发布的书籍和在线教程,许多 Spring Batch 项目仍然使用 XML 进行配置。在 SayakBanerjee 的辩护中,很难找到好的 Java 配置 Spring Boot 示例
【解决方案2】:

你错过了 @EnableBatchProcessing docs

【讨论】:

  • 不,我没有错过@EnableBatchProcessing - 我不想使用它,因为它会尝试自动加载 jobRepository 之类的所有内容,而我无法用我自己的 bean 覆盖它。跨度>
  • 没有它,批处理不会运行。您必须使用注释(参见 SimpleBatchConfiguration 及其父级的源代码)。要覆盖默认设置,请实现 BatchConfigurer docs.spring.io/spring-batch/apidocs/org/springframework/batch/…
  • 感谢您的回复。我也尝试过,当我这样做时,我得到:java.lang.ClassCastException: org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean$$EnhancerBySpringCGLIB$$581089fa cannot be cast to org.springframework.batch。 core.repository.JobRepository
  • &lt;bean class="org.springframework.batch.core.scope.StepScope"&gt; &lt;property name="proxyTargetClass" value="true" /&gt; &lt;/bean&gt; 添加到您的xml。见forum.spring.io/forum/spring-projects/batch/…stackoverflow.com/questions/27803053/…
  • 不幸的是,这并没有解决我的问题,我仍然遇到同样的异常。
猜你喜欢
  • 1970-01-01
  • 2011-07-27
  • 2021-12-07
  • 2019-06-09
  • 1970-01-01
  • 1970-01-01
  • 2019-07-14
  • 2021-09-03
  • 1970-01-01
相关资源
最近更新 更多