I'm using org.springframework.scheduling.quartz.CronTriggerBean for trigger job.
Could you propose cron expression to trigger job execution only once on application startup pls?
I believe the actual answer is: no, you can't.
What you could do however when using Spring 3.1 (which is Milestone 2 at the time of writing) is create profiles which can be enabled for different environments. So you can use different beans and bean configurations depending on profiles you enable.
Instead of using scheduling, I would prefer to invoke your trigger via defining an init-method in your spring configuration
To run a job only once at startup with the Spring Quartz scheduler you can use the org.springframework.scheduling.quartz.SimpleTriggerBean which doesn't take a cronExpression but a startDelay and a repeatCount. Set the repeatCount to 0 for a single execution (see Quartz documentation on SimpleTrigger for further options).
<bean id="doJobOnceOnStartupTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="myJobDetail" />
<property name="startDelay" value="5000" />
<property name="repeatCount" value="0" />
</bean>
<bean id="myJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="myBean" />
<property name="targetMethod" value="myMethod" />
</bean>
Additional information can be found int the
spring documentation: Chapter 22. Scheduling jobs using Quartz or Timer
You can use a SimpleTriggerBean - with a cron expression, you won't achieve this
Related
I am deploying an application where I need to maintain some data in Ignite cache. I used in memory Ignite cache. Here is the Ignite configuration I have used:
<property name="cacheConfiguration">
<list>
<bean
class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="IGNITE_DATA" />
<property name="cacheMode" value="PARTITIONED" />
<property name="atomicityMode" value="ATOMIC" />
<property name="writeSync"
value="PRIMARY_SYNC" />
<property name="backups"
value="${IGNITE_CACHE_BACKUPS}" />
</bean>
</list>
</property>
Now when I deployed multiple instances of my application and stored data in Ignite cache. Its shared among all the application instances.
Even if any any instance goes down and comes up after sometime it has the latest data via Ignite cache sync.
But issue occurs when all the application instances go down. When they come up data is gone since it was not persisted. For persistence I used dataStorageConfiguration property and enabled the persistence. Here is the change I added to Ignite configuration:
<property name="dataStorageConfiguration">
<bean
class="org.apache.ignite.configuration.DataStorageConfiguration">
<!-- Enabling Apache Ignite Persistent Store. -->
<property name="defaultDataRegionConfiguration">
<bean
class="org.apache.ignite.configuration.DataRegionConfiguration">
<property name="persistenceEnabled" value="true" />
</bean>
</property>
<!-- Changing Write Ahead Log Mode. -->
<property name="storagePath" value="${IGNITE_BC_STORE_PATH}"/>
<property name="walMode" value="LOG_ONLY" />
</bean>
</property>
Now when I deploy my application and I try and start Ignite from Java code as mentioned below:
log.info("Initializing IGNITE...");
ignite = Ignition.start(getClass().getResource(CONF_FILE));
I get an exception every time stating the default instance has already started.Tried several things but didn't work. Even if I remove the CacheConfiguration from Ignite Configuration and just keep dataStorageConfiguration I still getting the same error. Error is :
Caused by: class org.apache.ignite.IgniteCheckedException: Default Ignite instance has already been started.
at org.apache.ignite.internal.IgnitionEx.start0(IgnitionEx.java:1141)
at org.apache.ignite.internal.IgnitionEx.startConfigurations(IgnitionEx.java:1076)
at org.apache.ignite.internal.IgnitionEx.start(IgnitionEx.java:962)
at org.apache.ignite.internal.IgnitionEx.start(IgnitionEx.java:881)
at org.apache.ignite.Ignition.start(Ignition.java:373)
Normally this error comes when we try and run multiple Ignite nodes under same JVM but here I am running single node per JVM. Then also getting the error.
Please do correct me if I am wrong.
Any help here will be appreciated.
Most probably, you have more than one IgniteConfiguration bean in your config file. If one configuration bean extends another one, then make sure, that the parent is abstract.
I have resolved the issue. Seems like the issue was not woth the Ignite configuration but was with Spring Framework configuration.
I was creating the bean for the Ignite class using the lazy-init=true. I switched that to the eager-init and that resolved my issue.
Not sure how exactly it solved this but it worked at least in my case.
I have seen various thread on timertask issues. However I would like some clarification on the inner working on spring Scheduler APIs (3.1).
I have a requirement to kick off a timer every 10 secs. The application runs in clustered websphere zos. (atleast 4 jvm nodes).
Here is the wiring.
<bean id="dataProcessSchedulerTask" class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="targetObject" ref="ondataTransferTimerWakeupService" />
<property name="targetMethod" value="processDataFeedMetadata" />
</bean>
<bean id="DATA_PROCESS_TIMER"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask" ref="DATAProcessSchedulerTask" />
<property name="delay" value="#{systemProperties.DATA_PROCESS_TIMER}" />
<property name="period" value="#{systemProperties.DATA_PROCESS_TIMER}" />
</bean>
<bean class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
list>
<ref bean="DATA_PROCESS_TIMER" />
</list>
</property>
</bean>
<bean id="onDATATransferTimerWakeupService" class="com.serviceimpl.OnDATATransferTimerWakeupService" />
I have defined (#async) for processDataFeedMetadata method.
The problem I am seeing the timer which fires every 10 secs correctly to begin with (4 jvms - 24 timer occurrences every min), started misbehaving after few hours (2 or 3 jvms stop firing any timer at all - 6 to 12 timer occurrences every min). I understand timertask implementation has it's own limitation. However, if I invoke an ASYNC method from MethodInvokingTimerTaskFactoryBean, Why would the timertask misbehave as
(1) timer should complete well within the interval as soon as it invokes ASYNC method.
(2) I don't see any exception from app logs and MethodInvokingTimerTaskFactoryBean should have handled and consume any exception if there are any.
Really appreciate if anyone has input on what is going on here ?
I suggest you utilizing Quartz Scheduler for Spring Scheduler implementation
http://quartz-scheduler.org/
Do you have this problem with 1 jvm ?
I have set up an spring http invoker example as described here http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/remoting.html in section 20.4
If i do several service calls in a row (see my for-loop), between the single calls is one second though the server processes the method in less than 4ms.
Any ideas.
Stefan
Here the config and call:
<!-- server side -->
<bean name="configurationServiceExporter"
class="org.springframework.remoting.httpinvoker.SimpleHttpInvokerServiceExporter">
<property name="service" ref="configurationService" />
<property name="serviceInterface"
value="remote.service.ConfigurationService" />
</bean>
<bean id="httpServer"
class="org.springframework.remoting.support.SimpleHttpServerFactoryBean">
<property name="contexts">
<util:map>
<entry key="/remoting/ConfigurationService" value-ref="configurationServiceExporter" />
</util:map>
</property>
<property name="port" value="${port.httpinvoker}" />
</bean>
<!-- client side -->
<bean id="configurationServiceProxy" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl"
value="http://localhost:7777/remoting/ConfigurationService" />
<property name="serviceInterface"
value="remote.service.ConfigurationService" />
</bean>
/** here the service call*/
#Component
public class ServiceConsumer {
private ConfigurationService configurationService;
public void do(){
for (int i = 0; i < 10; i++)
this.configurationService.getConfigurationValue(SMTP_HOST);
}
I just encountered the very same problem:
Spring Remoting
Delays of "exactly" 1 second
Java 7
Unfortunately, I was unable to find a reason for this odd behavior, but there exists a workaround: use jetty instead of the SimpleHttpServerFactoryBean.
This boils down to changing the xml configuration a little, how exactly is described here.
The delays disappeared; firing requests even seems to have sped up compared to using SimpleHttpServerFactoryBean in Java 6.
Found the Problem. It was not connected to Spring HTTP Invoker. I updated to Java 7. When i ran my app with Java 6 it works as before the update (without waiting one second between the requests. If i knew anything more, i come back.
I am using quartz to schedule a spring batch job.
The job reads a file from a folder( which has multiple files ) does some processing and copies it to another folder.
is it possible to create multiple instances of the job, that will run concurrenty,reading multiple files ?
My question is :
In spring batch, is it possible to spawn multiple instances of the same job? I am using quartz schedular ?
In Spring Batch it is possible to start several jobs, provided you have supplied different JobParameters for each jobLauncher.run() call. jobLauncher in your Spring configuration will spawn each job in a separate thread, if it is configured with appropriate task executor:
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
<property name="taskExecutor" ref="taskExecutor" />
</bean>
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"
p:corePoolSize="5"
p:maxPoolSize="30" />
It is possible with Quartz, using a MethodInvokingJobDetailFactoryBean, for instance:
<bean id="myjob"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="someBean" />
</property>
<property name="targetMethod" value="someMethod" />
<!-- The concurrent property is already true by default
<property name="concurrent" value="true" />
-->
</bean>
Citing the Spring documentation
By default, Quartz Jobs are stateless, resulting in the possibility of jobs interfering with each other. If you specify two triggers for the same JobDetail, it might be possible that before the first job has finished, the second one will start. If JobDetail classes implement the Stateful interface, this won't happen. The second job will not start before the first one has finished. To make jobs resulting from the MethodInvokingJobDetailFactoryBean non-concurrent, set the concurrent flag to false.
I have a simple Spring Scheduled Taks defined by the following:
<context:component-scan base-package="com/test"/>
<task:scheduled-tasks>
<task:scheduled ref="myScheduler" method="doMyTask" fixed-rate="300000"/>
</task:scheduled-tasks>
<task:scheduler id="taskScheduler" pool-size="1"/>
<task:executor id="executorWithPoolSizeRange"
pool-size="1"
queue-capacity="100"/>
<bean id="cleanupClass" class="com.test.CleanupClass">
<property name="myProperty" value="3600"/>
</bean>
I would like to run a single thread synchronously every 5 minutes. However, what I get is FIVE instances of the task running consecutively every 5 minutes. Does anyone know if there is something missing from the XML description above?
I got the behavior I wanted using the #Scheduled annotations but I would rather not use annotation for the fixed-rate as I want it to be configurable outside of the code.
Thanks.
the following worked for me:
<bean id="task" class="com.foo.MyTask">
<task:scheduled-tasks scheduler="scheduler">
<task:scheduled ref="task" method="run" fixed-delay="300000" />
</task:scheduled-tasks>
<task:scheduler id="scheduler" pool-size="10" />
Greetings,
Mark
Is this the behavior you are seeing in the STS when you deploy it to tomcat? If so, you would want to undeploy the application, redeploy it and restart the application.
Another idea is to use SPEL expression from a properties file to use it with #Sched annotation. In that way it is still configurable while using that annotation.