Why #Scheduled is not working in Spring Boot? - spring

I am trying to add scheduled job to my application.
I have created bean that has method annotated with #Scheduled. Also I have added #EnableScheduling to my ApplicationConfig class.
But it doesn't work. My application does not start as it starts usually, and the application port does not open, and there is no stacktrace with errors.
Logs end with
INFO o.s.s.c.ThreadPoolTaskScheduler [] : Initializing ExecutorService 'taskScheduler'
but not as usual with
Started MyApp in 11.136 seconds
Code:
#Configuration
#EnableAsync
#EnableScheduling
public class ApplicationConfig implements AsyncConfigurer {
#Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new CustomAsyncExceptionHandler();
}
#Bean(name = "publisherPoolTaskExecutor")
public Executor publishPoolTaskExecutor() {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setThreadNamePrefix("publisher-");
executor.initialize();
return executor;
}
#Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
#Component
public class JobService {
private static final Logger log = LoggerFactory.getLogger(JobService.class);
#Scheduled(fixedDelay = 60000L)
public void doWork() {
log.info("Working...");
}
}
Async is not used in my scheduler, it's for other purpose.
Logs that appear at the end
2022-08-08 16:43:35.112 [scheduling-1] INFO o.hibernate.jpa.internal.util.LogHelper [traceId=40196fb09b21f5ba, spanId=40196fb09b21f5ba, spanExportable=false, X-Span-Export=false, X-B3-SpanId=40196fb09b21f5ba, X-B3-TraceId=40196fb09b21f5ba] : HHH000204: Processing PersistenceUnitInfo [name: default]
2022-08-08 16:43:35.155 [scheduling-1] INFO org.hibernate.Version [traceId=40196fb09b21f5ba, spanId=40196fb09b21f5ba, spanExportable=false, X-Span-Export=false, X-B3-SpanId=40196fb09b21f5ba, X-B3-TraceId=40196fb09b21f5ba] : HHH000412: Hibernate ORM core version 5.4.15.Final
2022-08-08 16:43:35.267 [scheduling-1] INFO o.hibernate.annotations.common.Version [traceId=40196fb09b21f5ba, spanId=40196fb09b21f5ba, spanExportable=false, X-Span-Export=false, X-B3-SpanId=40196fb09b21f5ba, X-B3-TraceId=40196fb09b21f5ba] : HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
2022-08-08 16:43:35.347 [scheduling-1] INFO com.zaxxer.hikari.HikariDataSource [traceId=40196fb09b21f5ba, spanId=40196fb09b21f5ba, spanExportable=false, X-Span-Export=false, X-B3-SpanId=40196fb09b21f5ba, X-B3-TraceId=40196fb09b21f5ba] : HikariPool-1 - Starting...
2022-08-08 16:43:35.389 [scheduling-1] INFO com.zaxxer.hikari.HikariDataSource [traceId=40196fb09b21f5ba, spanId=40196fb09b21f5ba, spanExportable=false, X-Span-Export=false, X-B3-SpanId=40196fb09b21f5ba, X-B3-TraceId=40196fb09b21f5ba] : HikariPool-1 - Start completed.
2022-08-08 16:43:35.406 [scheduling-1] INFO org.hibernate.dialect.Dialect [traceId=40196fb09b21f5ba, spanId=40196fb09b21f5ba, spanExportable=false, X-Span-Export=false, X-B3-SpanId=40196fb09b21f5ba, X-B3-TraceId=40196fb09b21f5ba] : HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
2022-08-08 16:43:35.572 [scheduling-1] WARN org.hibernate.cfg.AnnotationBinder [traceId=40196fb09b21f5ba, spanId=40196fb09b21f5ba, spanExportable=false, X-Span-Export=false, X-B3-SpanId=40196fb09b21f5ba, X-B3-TraceId=40196fb09b21f5ba] : HHH000457: Joined inheritance hierarchy [com.xxx.MyEntity] defined explicit #DiscriminatorColumn. Legacy Hibernate behavior was to ignore the #DiscriminatorColumn. However, as part of issue HHH-6911 we now apply the explicit #DiscriminatorColumn. If you would prefer the legacy behavior, enable the `hibernate.discriminator.ignore_explicit_for_joined` setting (hibernate.discriminator.ignore_explicit_for_joined=true)
2022-08-08 16:43:36.131 [scheduling-1] INFO o.h.e.t.j.p.i.JtaPlatformInitiator [traceId=40196fb09b21f5ba, spanId=40196fb09b21f5ba, spanExportable=false, X-Span-Export=false, X-B3-SpanId=40196fb09b21f5ba, X-B3-TraceId=40196fb09b21f5ba] : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Code of the AsyncUncaughtExceptionHandler:
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(CustomAsyncExceptionHandler.class);
#Override
public void handleUncaughtException(
#NonNull Throwable ex,
Method method,
#NonNull Object... params) {
log.error(
String.format(
"Error while executing async method [%s] with parameters [%s]: %s",
method.getName(),
Stream.of(params).map(Object::toString).collect(joining(",")),
ex.getMessage()
),
ex
);
}
}

I have implemented SchedulingConfigurer in my config and it works for me.
Example of configuration:
#Configuration
#EnableScheduling
public class SchedulingConfig implements SchedulingConfigurer {
#Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskScheduler());
}
#Bean
public Executor taskScheduler() {
ThreadPoolTaskScheduler t = new ThreadPoolTaskScheduler();
t.setPoolSize(1);
t.setThreadNamePrefix("scheduler - ");
t.initialize();
return t;
}
}

Related

JobParametersValidator.validate() method parameters returns null in spring batch

I am writing simple helloworld application in spring batch, and I'm trying to validate the JobParameters with custom implementation of JobParametersValidator.
public class ParameterValidator implements JobParametersValidator{
#Override
public void validate(JobParameters parameters) throws JobParametersInvalidException {
//String parameter = parameters.getParameters().get("outputText");
System.out.println("jobparameters are ............ " + parameters);
//System.out.println("parameter is " + parameter);
//if(!StringUtils.hasText(parameter)) {
throw new JobParametersInvalidException("Parameter is missing.........");
//}
}
}
But when I tried to Sysout the JobParameters inside the validate method, parameters return null.
Here is my console out.
2021-11-26 10:06:32.457 INFO 11912 --- [ restartedMain] com.pack.SpringBatchDemo2Application : Starting SpringBatchDemo2Application using Java 16.0.2 on DESKTOP-T1L7IA7 with PID 11912 (D:\Workspace\EclipseWorkspaceSpringPractise\SpringBatchDemo2\target\classes started by arepa in D:\Workspace\EclipseWorkspaceSpringPractise\SpringBatchDemo2)
2021-11-26 10:06:32.458 INFO 11912 --- [ restartedMain] com.pack.SpringBatchDemo2Application : No active profile set, falling back to default profiles: default
2021-11-26 10:06:32.536 INFO 11912 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2021-11-26 10:06:33.575 INFO 11912 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2021-11-26 10:06:33.784 INFO 11912 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2021-11-26 10:06:33.920 INFO 11912 --- [ restartedMain] o.s.b.c.r.s.JobRepositoryFactoryBean : No database type set, using meta data indicating: POSTGRES
2021-11-26 10:06:34.262 INFO 11912 --- [ restartedMain] o.s.b.c.l.support.SimpleJobLauncher : No TaskExecutor has been set, defaulting to synchronous executor.
2021-11-26 10:06:34.484 INFO 11912 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2021-11-26 10:06:34.539 INFO 11912 --- [ restartedMain] com.pack.SpringBatchDemo2Application : Started SpringBatchDemo2Application in 2.596 seconds (JVM running for 4.056)
2021-11-26 10:06:34.544 INFO 11912 --- [ restartedMain] o.s.b.a.b.JobLauncherApplicationRunner : Running default command line with: []
jobparameters are ............ {}
2021-11-26 10:06:34.713 INFO 11912 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-11-26 10:06:34.756 ERROR 11912 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
Here is my Job creation code.
#Component
public class HelloWorldJob {
#Autowired
private JobBuilderFactory jobBuilderFactory;
#Autowired
private StepBuilderFactory stepBuilderFactory;
public Step step() {
Tasklet tasklet = (contribution, chunkContext) -> {
return RepeatStatus.FINISHED;
};
return this.stepBuilderFactory.get("step1")
.tasklet(tasklet).build();
}
#Bean
public Job job() {
return this.jobBuilderFactory.get("job1").start(step()).validator(new ParameterValidator()).build();
}
}
Here is my code for triggering jobs.
#Component
public class TriggerJobLauncher {
#Autowired
private JobLauncher launcher;
#Autowired
private Job job;
public void triggerJob() throws JobExecutionAlreadyRunningException,
JobRestartException,
JobInstanceAlreadyCompleteException,
JobParametersInvalidException {
JobParameters parameters = new JobParametersBuilder().addParameter("aa", new JobParameter("Hello World")).toJobParameters();
launcher.run(job, parameters);
}
}

What happens when i using #Bean and #Component annotations together?

I'm trying to configure my spring security application.
I want to create my own UserDetailsService.
For that i do something like this:
public class ApplicationUserService implements UserDetailsService {
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return this.someUser();
}
}
I got 2 ways to add this UserService to Spring Security
Add it to configuration class. Something like this:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
#Override
protected UserDetailsService userDetailsService() {
return applicationUserService;
}
}
Or add annotaion #Component, or #Service on my class.
Everything is working fine when i chose only 1 way, but i got an question: why when i trying to use both variants (add #Service and add #Bean to config) nothing is working?
I got no exceptions, error or something like this in console:
2021-09-11 17:26:16.755 INFO 15819 --- [ main] com.example.test.TestApplication : Starting TestApplication using Java 16.0.2 on aleksander-MS-7A71 with PID 15819 (/home/aleksander/programming/java/4fun/test/target/classes started by aleksander in /home/aleksander/programming/java/4fun/test)
2021-09-11 17:26:16.756 INFO 15819 --- [ main] com.example.test.TestApplication : No active profile set, falling back to default profiles: default
2021-09-11 17:26:17.402 INFO 15819 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-09-11 17:26:17.409 INFO 15819 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-09-11 17:26:17.409 INFO 15819 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.52]
2021-09-11 17:26:17.442 INFO 15819 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-09-11 17:26:17.442 INFO 15819 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 630 ms
2021-09-11 17:26:17.555 INFO 15819 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#6981f8f3, org.springframework.security.web.context.SecurityContextPersistenceFilter#38bb9d7a, org.springframework.security.web.header.HeaderWriterFilter#62db3891, org.springframework.security.web.authentication.logout.LogoutFilter#48528634, org.springframework.security.web.authentication.www.BasicAuthenticationFilter#80bfdc6, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#78d6447a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#5e65afb6, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#623dcf2a, org.springframework.security.web.session.SessionManagementFilter#2819c460, org.springframework.security.web.access.ExceptionTranslationFilter#6f49d153, org.springframework.security.web.access.intercept.FilterSecurityInterceptor#60bbacfc]
2021-09-11 17:26:17.676 INFO 15819 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-09-11 17:26:17.682 INFO 15819 --- [ main] com.example.test.TestApplication : Started TestApplication in 1.215 seconds (JVM running for 1.794)
The way you've described the question, the application will definitely throw an exception unless you've defined the bean preference.
First case:
Basically, UserDetailsService is an interface and you've provided the implementation of it by declaring the bean as
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
#Override
protected UserDetailsService userDetailsService() {
return new ApplicationUserService();
}
}
Second case: You want to check the behaviour by declaring another bean using #Service or #Component annotation as following
#Service
public class ApplicationUserService implements UserDetailsService {
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return new UserDetails();
}
}
If you try to use the above cases together, it won't work. The case is very simple you are providing two beans of type UserDetailsService to the spring container and hence it won't be able to identify which one it should use.
If you want to check the behaviour with both the cases you've to set the priority for beans, so in that case you can mark one of the bean with #Primary annotation.
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Primary
#Bean
#Override
protected UserDetailsService userDetailsService() {
return new ApplicationUserService();
}
}

How to fix The injection point has the following annotations: - #org.springframework.beans.factory.annotation.Autowired(required=true)

I am new to spring boot, i am getting this error since a while, unfortunately can't fix it. I am googling since then but still not find what i did wrong. Find below my code:
Entity
#Entity
#Table(name="compagnie")
public class Compagnie implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id_compagnie")
private int idCompagnie;
#Column(name="nom_compagnie")
private String nomCompagnie;
#Column(name="nom_court_compagnie")
private String nomCourtCompagnie;
#Column(name="logo_compagnie")
private String logoCompagnie;
public int getIdCompagnie() {
return idCompagnie;
}
public void setIdCompagnie(int idCompagnie) {
this.idCompagnie = idCompagnie;
}
public String getNomCompagnie() {
return nomCompagnie;
}
public void setNomCompagnie(String nomCompagnie) {
this.nomCompagnie = nomCompagnie;
}
public String getNomCourtCompagnie() {
return nomCourtCompagnie;
}
public void setNomCourtCompagnie(String nomCourtCompagnie) {
this.nomCourtCompagnie = nomCourtCompagnie;
}
public String getLogoCompagnie() {
return logoCompagnie;
}
public void setLogoCompagnie(String logoCompagnie) {
this.logoCompagnie = logoCompagnie;
}
}
Dao
#Component
public interface CompagnieDao extends JpaRepository<Compagnie, Integer> {
#Query("select c from Compagnie c where idCompagnie != :idCompagnie")
List<Compagnie> getAllCompagnieNonAssurAstuce(#Param("idCompagnie") int idCompagnie);
#Query("select c from Compagnie c where nomCompagnie = :nomCompagnie")
Compagnie getCompagnieByNom(#Param("nomCompagnie") String nomCompagnie);
}
Main
#SpringBootApplication
public class Application implements CommandLineRunner {
#Autowired
private CompagnieDao compagnieDao;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(String... args) throws Exception {
System.out.println("tic toc");
List<Compagnie> compagnies = compagnieDao.findAll();
compagnies.forEach(compagnie -> System.out.println(compagnie.getNomCompagnie()));
}
}
Error
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-12-30 11:54:42.817 ERROR 10136 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
APPLICATION FAILED TO START
Description:
Field compagnieDao in com.assurastuce.Application required a bean of type 'com.dao.CompagnieDao' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.dao.CompagnieDao' in your configuration.
Thank you for your help
I changed the spring version from 2.4.1 to 2.3.4.RELEASE and now getting this error
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) [spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:779) [spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) [spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at com.assurastuce.Application.main(Application.java:20) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_271]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_271]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_271]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_271]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.3.4.RELEASE.jar:2.3.4.RELEASE]
Caused by: java.lang.NullPointerException: null
at com.assurastuce.Application.run(Application.java:26) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) [spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
... 10 common frames omitted
2020-12-31 08:26:45.401 INFO 11520 --- [ restartedMain] o.e.jetty.server.AbstractConnector : Stopped ServerConnector#19b4bd36{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2020-12-31 08:26:45.401 INFO 11520 --- [ restartedMain] org.eclipse.jetty.server.session : node0 Stopped scavenging
2020-12-31 08:26:45.405 INFO 11520 --- [ restartedMain] o.e.j.s.h.ContextHandler.application : Destroying Spring FrameworkServlet 'dispatcherServlet'
2020-12-31 08:26:45.407 INFO 11520 --- [ restartedMain] o.e.jetty.server.handler.ContextHandler : Stopped o.s.b.w.e.j.JettyEmbeddedWebAppContext#4bfa6d74{application,/,[file:///C:/Users/LAKATAN%20Adebayo%20G.%20W/AppData/Local/Temp/jetty-docbase.8010039629830210588.8080/],UNAVAILABLE}
2020-12-31 08:26:45.430 INFO 11520 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-12-31 08:26:45.434 INFO 11520 --- [ restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
2020-12-31 08:26:45.438 INFO 11520 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2020-12-31 08:26:45.465 INFO 11520 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
Probably the folder structure is not correct.
Could you please add this line of code and check if this works for you.
#SpringBootApplication
#ComponentScan(value = "com.dao.CompagnieDao")
public class Application implements CommandLineRunner {
Also, I think it would be more correct if you replace the #Component with the #Repository annotation.
#Repository
public interface CompagnieDao extends JpaRepository<Compagnie, Integer> {

Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered

I know this has been asked many time but I could not
find answer for I problem. I am Trying to schedule my spring batch for every 20 second but its getting fail.
QuartzConfiguration.java
#Configuration
public class QuartzConfiguration {
#Autowired
private JobLauncher jobLauncher;
#Autowired
private JobLocator jobLocator;
#Bean
public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) {
JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = new JobRegistryBeanPostProcessor();
jobRegistryBeanPostProcessor.setJobRegistry(jobRegistry);
return jobRegistryBeanPostProcessor;
}
#Bean
public JobDetailFactoryBean jobDetailFactoryBean() {
JobDetailFactoryBean jobfactory = new JobDetailFactoryBean();
jobfactory.setJobClass(QuartzJobLauncher.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("jobName", "Test_Job");
map.put("jobLauncher", jobLauncher);
map.put("jobLocator", jobLocator);
jobfactory.setJobDataAsMap(map);
jobfactory.setGroup("group");
jobfactory.setName("job");
return jobfactory;
}
// Job is scheduled after every 20 sec
#Bean
public CronTriggerFactoryBean cronTriggerFactoryBean() {
CronTriggerFactoryBean ctFactory = new CronTriggerFactoryBean();
ctFactory.setJobDetail(jobDetailFactoryBean().getObject());
ctFactory.setStartDelay(3000);
ctFactory.setName("cron_trigger");
ctFactory.setGroup("cron_group");
ctFactory.setCronExpression("0/20 * * * * ?");
return ctFactory;
}
#Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
scheduler.setTriggers(cronTriggerFactoryBean().getObject());
return scheduler;
}
}
QuartzJobLauncher.java
public class QuartzJobLauncher extends QuartzJobBean {
private static final Logger log = LoggerFactory.getLogger(QuartzJobLauncher.class);
private String jobName;
private JobLauncher jobLauncher;
private JobLocator jobLocator;
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public JobLauncher getJobLauncher() {
return jobLauncher;
}
public void setJobLauncher(JobLauncher jobLauncher) {
this.jobLauncher = jobLauncher;
}
public JobLocator getJobLocator() {
return jobLocator;
}
public void setJobLocator(JobLocator jobLocator) {
this.jobLocator = jobLocator;
}
#Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
Job job = jobLocator.getJob(jobName);
JobExecution jobExecution = jobLauncher.run(job, new JobParameters());
log.info("{}_{} was completed successfully", job.getName(), jobExecution.getId());
} catch (Exception e) {
log.error("Encountered job execution exception!");
}
}
}
BatchConfig.java
#Configuration
public class BatchConfig {
#Autowired
JobBuilderFactory jobBuilderFactory;
#Autowired
StepBuilderFactory stepBuilderFactory;
#Bean
public Tasklet task1()
{
return new Tasklet(){
#Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
// TODO Auto-generated method stub
System.out.println("hello world");
return RepeatStatus.FINISHED;
}
};
}
#Bean
public Step step1(){
return stepBuilderFactory.get("step1")
.tasklet(task1())
.build();
}
#Bean
public Job job1()
{
return jobBuilderFactory.get("job1")
.start(step1())
.build();
}
}
BatchApplication.java
#SpringBootApplication
#EnableBatchProcessing
#Import(QuartzConfiguration.class)
public class BatchApplication {
public static void main(String[] args) {
SpringApplication.run(BatchApplication.class, args);
}
}
error log
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.4.RELEASE)
2017-07-11 14:35:59.370 INFO 8868 --- [ main] com.schwab.cat.BatchApplication : Starting BatchApplication on KVMOF0487DVLBDC with PID 8868 (started by pankaj.k.singh in C:\Users\pankaj.k.singh\Desktop\batch\sample hello world)
2017-07-11 14:35:59.377 INFO 8868 --- [ main] com.schwab.cat.BatchApplication : No active profile set, falling back to default profiles: default
2017-07-11 14:35:59.511 INFO 8868 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#221af3c0: startup date [Tue Jul 11 14:35:59 IST 2017]; root of context hierarchy
2017-07-11 14:36:00.992 WARN 8868 --- [ main] o.s.c.a.ConfigurationClassEnhancer : #Bean method ScopeConfiguration.stepScope is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as #Autowired, #Resource and #PostConstruct within the method's declaring #Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see #Bean javadoc for complete details.
2017-07-11 14:36:01.013 WARN 8868 --- [ main] o.s.c.a.ConfigurationClassEnhancer : #Bean method ScopeConfiguration.jobScope is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as #Autowired, #Resource and #PostConstruct within the method's declaring #Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see #Bean javadoc for complete details.
2017-07-11 14:36:01.230 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Tomcat' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Tomcat] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.253 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$1bb5301] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.435 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.632 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'dataSource' of type [org.apache.tomcat.jdbc.pool.DataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.641 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$$EnhancerBySpringCGLIB$$e3aef661] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.672 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'dataSourceInitializer' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.679 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration' of type [org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$$EnhancerBySpringCGLIB$$17e2d67] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.718 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'jobLauncher' of type [com.sun.proxy.$Proxy41] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.732 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'jobRegistry' of type [com.sun.proxy.$Proxy43] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.733 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'com.quantvalley.batch.quartz.QuartzConfiguration' of type [com.quantvalley.batch.quartz.QuartzConfiguration$$EnhancerBySpringCGLIB$$88291ebb] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:03.256 INFO 8868 --- [ main] o.s.b.c.r.s.JobRepositoryFactoryBean : No database type set, using meta data indicating: HSQL
2017-07-11 14:36:03.606 INFO 8868 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : No TaskExecutor has been set, defaulting to synchronous executor.
2017-07-11 14:36:03.912 INFO 8868 --- [ main] org.quartz.impl.StdSchedulerFactory : Using default implementation for ThreadExecutor
2017-07-11 14:36:03.980 INFO 8868 --- [ main] org.quartz.core.SchedulerSignalerImpl : Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2017-07-11 14:36:03.984 INFO 8868 --- [ main] org.quartz.core.QuartzScheduler : Quartz Scheduler v.2.2.3 created.
2017-07-11 14:36:03.987 INFO 8868 --- [ main] org.quartz.simpl.RAMJobStore : RAMJobStore initialized.
2017-07-11 14:36:03.991 INFO 8868 --- [ main] org.quartz.core.QuartzScheduler : Scheduler meta-data: Quartz Scheduler (v2.2.3) 'schedulerFactoryBean' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
2017-07-11 14:36:03.993 INFO 8868 --- [ main] org.quartz.impl.StdSchedulerFactory : Quartz scheduler 'schedulerFactoryBean' initialized from an externally provided properties instance.
2017-07-11 14:36:03.993 INFO 8868 --- [ main] org.quartz.impl.StdSchedulerFactory : Quartz scheduler version: 2.2.3
2017-07-11 14:36:03.998 INFO 8868 --- [ main] org.quartz.core.QuartzScheduler : JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory#20312893
2017-07-11 14:36:04.335 INFO 8868 --- [ main] o.s.jdbc.datasource.init.ScriptUtils : Executing SQL script from class path resource [org/springframework/batch/core/schema-hsqldb.sql]
2017-07-11 14:36:04.366 INFO 8868 --- [ main] o.s.jdbc.datasource.init.ScriptUtils : Executed SQL script from class path resource [org/springframework/batch/core/schema-hsqldb.sql] in 25 ms.
2017-07-11 14:36:04.733 INFO 8868 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2017-07-11 14:36:04.748 INFO 8868 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
2017-07-11 14:36:04.749 INFO 8868 --- [ main] o.s.s.quartz.SchedulerFactoryBean : Starting Quartz Scheduler now
2017-07-11 14:36:04.750 INFO 8868 --- [ main] org.quartz.core.QuartzScheduler : Scheduler schedulerFactoryBean_$_NON_CLUSTERED started.
2017-07-11 14:36:04.773 INFO 8868 --- [ main] com.schwab.cat.BatchApplication : Started BatchApplication in 6.481 seconds (JVM running for 11.417)
2017-07-11 14:36:20.039 ERROR 8868 --- [ryBean_Worker-1] c.q.batch.quartz.QuartzJobLauncher : Encountered job execution exception!
2017-07-11 14:36:40.006 ERROR 8868 --- [ryBean_Worker-2] c.q.batch.quartz.QuartzJobLauncher : Encountered job execution exception!
2017-07-11 14:37:00.001 ERROR 8868 --- [ryBean_Worker-3] c.q.batch.quartz.QuartzJobLauncher : Encountered job execution exception!
2017-07-11 14:37:20.002 ERROR 8868 --- [ryBean_Worker-4] c.q.batch.quartz.QuartzJobLauncher : Encountered job execution exception!
2017-07-11 14:37:40.002 ERROR 8868 --- [ryBean_Worker-5] c.q.batch.quartz.QuartzJobLauncher : Encountered job execution exception!
2017-07-11 14:38:00.002 ERROR 8868 --- [ryBean_Worker-6] c.q.batch.quartz.QuartzJobLauncher : Encountered job execution exception!
Please someone look into it and let me know the problem.
You swallowed the exception in your try/catch and instead, you logged only the fact that exception occurrent, but not what kind of exception it was. If you change logging statement to this:
log.error("Encountered job execution exception!", e);
You'll see that the error says:
org.springframework.batch.core.launch.NoSuchJobException: No job configuration with the name [Test_Job] was registered
You have declared a job with name job1, not Test_Job so that's why you're getting the exception. You have to change job data map to:
map.put("jobName", "job1");
This will remove the exception, but your job will still run once as Spring Batch requires unique job parameters to restart it, see this answer for explanation.
So because of that, you have to modify your job execution to something like this (the simplest) to be able to run it continually:
#Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
Job job = jobLocator.getJob(jobName);
Map<String, JobParameter> parametersMap = new HashMap<>();
parametersMap.put("timestamp", new JobParameter(System.currentTimeMillis()));
JobParameters jobParameters = new JobParameters(parametersMap);
JobExecution jobExecution = jobLauncher.run(job, jobParameters);
log.info("{}_{} was completed successfully", job.getName(), jobExecution.getId());
} catch (Exception e) {
log.error("Encountered job execution exception!", e);
}
}

Spring MVC Rest API not working when implementing InitializingBean

I have a basic API setup with Spring MVC Rest as following.
public abstract class AbstractApi implements InitializingBean {
#Autowired
protected ValidatorFactory validatorFactory;
/* ... */
#Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(validatorFactory);
}
}
#Controller
#RequestMapping("books")
public class BookApi extends AbstractApi {
private final BookRepository bookRepository;
#Autowired
public BookApi(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Book> getBooks() {
return new ResponseEntity<>(bookRepository.findAll(), HttpStatus.OK);
}
}
The server returns 404 - Not Found if I send GET /books request with above configuration.
But, if I make AbstractApi un-implement InitializingBean, it works fine. Also, annotating #PostConstruct to afterPropertiesSet() instead of implementing InitializingBean works.
Why is Spring #Controller API not working when implementing InitializingBean?
Your code looks correct. I tested in on my own and everything works as expected. What I'm suggesting is to remove #Autowired ValidatorFactory in AbstractApi class just for testing purpose. Implementing InitializingBean is not related to the request mapping handler mapping. My working code is:
public abstract class AbstractApi implements InitializingBean {
#Override
public void afterPropertiesSet() throws Exception {
System.out.println("after properties set");
}
}
and my controller
#Controller
#RequestMapping("books")
public class BooksController extends AbstractApi {
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<String> getBooks() {
return new ResponseEntity<>("", HttpStatus.OK);
}
}
and starting log from tomcat:
2016-01-28 16:48:03.141 INFO 2238 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-01-28 16:48:03.317 INFO 2238 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2016-01-28 16:48:03.329 INFO 2238 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.23
2016-01-28 16:48:03.405 INFO 2238 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2016-01-28 16:48:03.405 INFO 2238 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1815 ms
2016-01-28 16:48:03.512 INFO 2238 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2016-01-28 16:48:03.515 INFO 2238 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
after properties set
Your current #RequestMapping("books") path is incorrectly specified. When running locally on port 8080 looks like http://localhost:8080books
and should be #RequestMapping("/books") - http://localhost:8080/books
give that a try.

Resources