diff --git a/docs/howto.md b/docs/howto.md index 52981c1d04..4868e2df5f 100644 --- a/docs/howto.md +++ b/docs/howto.md @@ -151,6 +151,14 @@ Tomcat APIs are quite rich so once you have access to the of ways. Or the nuclear option is to add your own `TomcatEmbeddedServletContainerFactory`. +## Use Tomcat 8 + +Tomcat 8 works with Spring Boot, but the default is to use Tomcat 7 +(so we can support Java 1.6 out of the box). You should only need to +change the classpath to use Tomcat 8 for it to work. The +[websocket sample](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-websocket/pom.xml) +shows you how to do that in Maven. + ## Configure Jetty Generally you can follow the advice [here](#discover.options) about diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java index e178a1af53..4cddf95839 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java @@ -16,7 +16,17 @@ package org.springframework.boot.autoconfigure.batch; +import javax.sql.DataSource; + +import org.springframework.batch.core.configuration.ListableJobLocator; +import org.springframework.batch.core.converter.JobParametersConverter; +import org.springframework.batch.core.explore.JobExplorer; +import org.springframework.batch.core.explore.support.JobExplorerFactoryBean; import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.core.launch.JobOperator; +import org.springframework.batch.core.launch.support.SimpleJobOperator; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ExitCodeGenerator; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -26,6 +36,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcOperations; import org.springframework.util.StringUtils; /** @@ -37,20 +48,23 @@ import org.springframework.util.StringUtils; * @author Dave Syer */ @Configuration -@ConditionalOnClass({ JobLauncher.class }) +@ConditionalOnClass({ JobLauncher.class, DataSource.class, JdbcOperations.class }) public class BatchAutoConfiguration { @Value("${spring.batch.job.name:}") private String jobName; + @Autowired(required = false) + private JobParametersConverter jobParametersConverter; + @Bean - @ConditionalOnMissingBean(BatchDatabaseInitializer.class) + @ConditionalOnMissingBean public BatchDatabaseInitializer batchDatabaseInitializer() { return new BatchDatabaseInitializer(); } @Bean - @ConditionalOnMissingBean(JobLauncherCommandLineRunner.class) + @ConditionalOnMissingBean @ConditionalOnBean(JobLauncher.class) @ConditionalOnExpression("${spring.batch.job.enabled:true}") public JobLauncherCommandLineRunner jobLauncherCommandLineRunner() { @@ -62,10 +76,34 @@ public class BatchAutoConfiguration { } @Bean - @ConditionalOnMissingBean(ExitCodeGenerator.class) + @ConditionalOnMissingBean @ConditionalOnBean(JobLauncher.class) public ExitCodeGenerator jobExecutionExitCodeGenerator() { return new JobExecutionExitCodeGenerator(); } + @Bean + @ConditionalOnMissingBean + public JobExplorer jobExplorer(DataSource dataSource) throws Exception { + JobExplorerFactoryBean factory = new JobExplorerFactoryBean(); + factory.setDataSource(dataSource); + factory.afterPropertiesSet(); + return (JobExplorer) factory.getObject(); + } + + @Bean + @ConditionalOnMissingBean + public JobOperator jobOperator(JobExplorer jobExplorer, JobLauncher jobLauncher, + ListableJobLocator jobRegistry, JobRepository jobRepository) throws Exception { + SimpleJobOperator factory = new SimpleJobOperator(); + factory.setJobExplorer(jobExplorer); + factory.setJobLauncher(jobLauncher); + factory.setJobRegistry(jobRegistry); + factory.setJobRepository(jobRepository); + if (this.jobParametersConverter != null) { + factory.setJobParametersConverter(this.jobParametersConverter); + } + return factory; + } + } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java index 63098e1366..7682694b12 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java @@ -32,6 +32,7 @@ import org.springframework.batch.core.JobExecutionException; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.explore.JobExplorer; import org.springframework.batch.core.job.AbstractJob; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.repository.JobRepository; @@ -75,6 +76,7 @@ public class BatchAutoConfigurationTests { PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); assertNotNull(this.context.getBean(JobLauncher.class)); + assertNotNull(this.context.getBean(JobExplorer.class)); assertEquals(0, new JdbcTemplate(this.context.getBean(DataSource.class)) .queryForList("select * from BATCH_JOB_EXECUTION").size()); }