Cron Expression is not working as expected in Spring Boot Application - spring

Can anyone share a working sample in Spring Boot Application that works with cron expression in configuration file?
I've tried using below code snippet to schedule an external application. This works in exact 10 minutes gap for 5 times and then stops.
<int:poller max-messages-per-poll="1" cron="0 0/10 * * * *" task-executor="commonThreadPoolTaskExecutor" />

Related

Spring scheduler is running twice

I have read a few posts on these issues but it did not fix the problem.
#Component
#EnableScheduling
public class NotificationScheduled {
#Scheduled(cron = "0 0/5 * * * ?")
public void email() {}
}
I tried adding spring.batch.job.enabled=false in the application property file but did not work.
I also read https://docs.spring.io/spring-framework/docs/3.0.x/reference/scheduling.html#scheduling-annotation-support-scheduled section 25.5.1
I am running scheduler for every 5 min. When scheduler is kicked of (5 is up), it calls the method twice right away. Please help as I am running out of options. Thank you
As soon as I start tomcat (8.5), I see two scheduling thread. Could it tomcat?
UPDATE - I was able to fix the by removing the following line from tomcat config/server.xml. This line was deploying my app twice. I was able to see that from tocat manager.
<Context docBase="myapp path="/myapp" reloadable="true" source="org.eclipse.jst.jee.server:myapp"/>
Thank you all for your inputs.
I was able to fix the by removing the following line from tomcat config/server.xml. This line was deploying my app twice. I was able to see that from tocat manager. <Context docBase="myapp path="/myapp" reloadable="true" source="org.eclipse.jst.jee.server:myapp"/>
Thank you all for your inputs.

Run batch only on one server

I have a Spring boot MVC and batch application. Both the batch and MVC share the DAO and Service layers so they are in the same war file. They are deployed into 4 cloud servers and there is a load balance and vip configured for the UI application. So the MVC application is fine.
The problem is as part of the batch i do FTP of a file to an external server and that external server FTPs the processed file back. The processed file comes back only to one among the 4 servers. So I want the batch to run only on 1 server. How do i suppress the batch from executing in the other servers.
Solution becomes easier as your 4 instances are running on 4 different cloud severs. The starting point of the batch can be a file poller. So if the file is dropped into the polled directory on server 1, the batch job on server 1 will be invoked. The other instances do nothing as there is no file dropped on that server.
You need to integrate file poller before spring batch. Something like this - http://docs.spring.io/spring-batch/reference/html/springBatchIntegration.html
<int:channel id="inboundFileChannel"/>
<int:channel id="outboundJobRequestChannel"/>
<int:channel id="jobLaunchReplyChannel"/>
<int-file:inbound-channel-adapter id="filePoller"
channel="inboundFileChannel"
directory="file:/tmp/myfiles/"
filename-pattern="*.csv">
<int:poller fixed-rate="1000"/>
</int-file:inbound-channel-adapter>
<int:transformer input-channel="inboundFileChannel"
output-channel="outboundJobRequestChannel">. <bean class="io.spring.sbi.FileMessageToJobRequest">
<property name="job" ref="personJob"/>
<property name="fileParameterName" value="input.file.name"/>
</bean>
</int:transformer>
<batch-int:job-launching-gateway request-channel="outboundJobRequestChannel"
reply-channel="jobLaunchReplyChannel"/>
This can be one of many approaches but a way to achieve is keep a value in property file and set it's value to Boolean true
Now handle your batch to run only if property file value is true.
This way it gives you flexibility to change the server you want to handle batch job.

spring batch vs quartz jobs?

I am new to batch processing. I am trying to start with simple scheduler and job. But i am confused b/w
spring batch vs quartz jobs. My understanding is
Quartz :- quartz provides both frameworks i.e scheduler framework and job framework(in case I do not want to use spring batch jobs). Right ?
Spring Batch :- It only provides the job framework . I have always send using Quatz schecduler to schedule spring batch jobs.
Does spring provides its own scheduler also ?
Quartz is a scheduling framework. Like "execute something every hour or every last Friday of the month"
Spring Batch is a framework that defines that "something" that will be executed.
You can define a job, that consists of steps. Usually, a step is something that consists of an item reader, an optional item processor, and an item writer, but you can define a custom step. You can also tell Spring Batch to commit every 10 items and a lot of other stuff.
You can use Quartz to start Spring Batch jobs.
So basically Spring Batch defines what should be done, and Quartz defines when it should be done.
There is answer for this question in official FAQ
How does Spring Batch differ from Quartz?
Is there a place for them both in a solution?
Spring Batch and Quartz have different goals. Spring Batch provides functionality for processing large volumes of data and Quartz provides functionality for scheduling tasks. So Quartz could complement Spring Batch, but are not excluding technologies. A common combination would be to use Quartz as a trigger for a Spring Batch job using a Cron expression and the Spring Core convenience SchedulerFactoryBean.
Does spring provides its own scheduler also?
Yes, using Spring TaskScheduler as follows:
<task:scheduled-tasks>
<task:scheduled ref="runScheduler" method="run" fixed-delay="5000" />
</task:scheduled-tasks>
<task:scheduled-tasks>
<task:scheduled ref="runScheduler" method="run" cron="*/5 * * * * *" />
</task:scheduled-tasks>
full example
With Quartz Scheduler as follows:
<!-- run every 10 seconds -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="jobDetail" />
<property name="cronExpression" value="*/10 * * * * ?" />
</bean>
</property>
</bean>
full example
Spring Batch: reads data from a datasource (table in a database, flat file, etc), processes that data. Then stores the data in another datasource and may be in another format.
I have made a tutorial in my blog on how to integrate Spring Boot 2, Spring batch and Quartz.
You can integrate Spring boot and spring batch and skip the Quartz integration.
Quartz is a scheduler that schedules a task in the future and it has its own metadata tables to manage the state of the jobs.

Spring+quartz should I make my own bean?

I need a job that can run every 1 minutes betwen 17h and 18h, it should not be relaunched if the job is unfinished.
The org.springframework.scheduling.quartz.CronTriggerBean seems to be what I need but I found nothing about concurrency.
Would you know a quartz bean which would fit my needs?
Every javadoc I found has almost all its link broken.
http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/scheduling/quartz/CronTriggerBean.html
Or will I have to make my own kind of bean?
quartz is in 1.8.5 and spring in 2.5.6
Thanks.
-Sure, the CronTriggerBean is suitable for your case. The expression you need is 0 * 17 * * ? and will run for every minute starting at 17.00 with the last trigger happening at 17.59.
-In order to disable concurrency, in newer versions you can put #DisallowConcurrentExecution over your job class. In 1.8 version I think that annotation is not supported, and instead you need to put "implements StatefulJob" in your job class so that it implements StatefulJob that can be run only by one thread a time
-a sample app using quartz 1.8 can be found at http://www.mkyong.com/spring/spring-quartz-scheduler-example/
The 2.5 JavaDoc can be found here.
In Spring 2.5 you can set a concurrent attribute in the XML when using MethodInvokingJobDetailFactoryBean. Setting it prevents multiple instances from running at the same time, but it should be noted that triggers will be queued up and launched when the previous instance of the job finishes.
Here is a sample:
<bean id="fooJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="fooManager" />
<property name="targetMethod" value="myJOb" />
<property name="concurrent" value="true"/>
</bean>

Spring scheduler tasks causes memory leak in tomcat

I have used spring scheduler to run methods using a cron timer as shown below . The application has atleast 50 scheduler beans of the same class mentioned in bold below. We create new beans by passing configuration parameters through an xml given in the property section. But we get an error from tomcat 6.0.36 which is shown as italics text below. Is this an issue , is there any way to overcome this error. If we add a lot of scheduled tasks as given below , will this not affect the application performance?
SEVERE: The web application [/App ] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal#757fad]) and a value of type [org.mozilla.javascript.Context[]] (value [[Lorg.mozilla.javascript.Context;#18e915a]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="taskSchedulerClass" method="callScheduler" cron="0 0/4 * * * *"/> </task:scheduled-tasks>
<task:scheduler id="myScheduler" pool-size="10"/>
**<bean id="taskSchedulerClass" class="com.abc.efg.util.xyz">**
<property name="xmlName" value="xyz.xml" /> </bean>
Rhino's context clean up has been improved only for tomcat 7 : https://issues.apache.org/bugzilla/show_bug.cgi?id=49159 . So you will still get in tomcat6. Your error does not seem related to your scheduler.

Resources