I need findItemByPIdEndDate() method of the MngtImpl class to be invoked every 5000ms, but nothing appears to be happening. Am I missing something?
<bean id="findItemByPIdEndDate" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="MngtImpl"/>
<property name="targetMethod" value="findItemByPIdEndDate"/>
<property name="repeatInterval" value="50000"/>
</bean>
#matt b I've read some of this, everything is new to me here ..so I came with this .. and again its not working, what am I missing this time ?
<bean id="findItemByPIdEndDate" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="MngtImpl" />
<property name="targetMethod" value="findItemByPIdEndDate" />
</bean>
<bean id="compareDateTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="findItemByPIdEndDate" />
<property name="startDelay" value="0" />
<property name="repeatInterval" value="50000" />
</bean>
For this task, the Chapter 23. Scheduling and Thread Pooling is your friend. That said, here is a short summary.
First, define your Job:
<bean id="findItemByPIdEndDate" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="MngtImpl"/>
<property name="targetMethod" value="findItemByPIdEndDate"/>
</bean>
Now, you need to schedule the job using a trigger and a SchedulerFactoryBean. For the trigger, I suggest to use a SimpleTriggerBean in your case:
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<!-- see the example of method invoking job above -->
<property name="jobDetail" ref="findItemByPIdEndDate" />
<!-- 10 seconds -->
<property name="startDelay" value="10000" />
<!-- repeat every 50 seconds -->
<property name="repeatInterval" value="50000" />
</bean>
To finalize everything, set up the SchedulerFactoryBean:
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
</bean>
You need a lot more plumbing than that to make Quartz work. Just declaring the MethodInvokingJobDetailFactoryBean on its own will do nothing.
However, Quartz is overkill for this, Java5+ can do this on its own. I suggest reading up on Spring's ScheduledExecutorFactoryBean, which in combination with MethodInvokingRunnable, allows you to invoke your method periodically.
What you've done so far is the equivalent of only instantiating a MethodInvokingJobDetailFactoryBean() - essentially all you've done is created the Job. Now you need to have some configuration for how it's scheduled, and what triggers it.
Take a look at the section in the Spring manual on Quartz.
Related
Current application is on Spring 3.2/JDK7/Quartz/Log4J2, I have following quartz jobs scheduled below
Spring Quartz tiggers
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="trigger1" />
<ref bean="trigger2" />
<ref bean="trigger3" />
<ref bean="trigger4" />
<ref bean="trigger5" />
</list>
</property>
</bean>
Job interval definition
<bean id="trigger1" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="scheduledService1" />
<property name="startDelay" value="5000" />
<property name="repeatInterval" value="2900" />
</bean>
<bean id="trigger2" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="scheduledService2" />
<property name="startDelay" value="7000" />
<property name="repeatInterval" value="3000" />
</bean>
<bean id="trigger3" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="scheduledService3" />
<property name="startDelay" value="9000" />
<property name="repeatInterval" value="3100" />
</bean>
<bean id="trigger4" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="scheduledService4" />
<property name="startDelay" value="11000" />
<property name="repeatInterval" value="3200" />
</bean>
<bean id="trigger5" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="scheduledService5" />
<property name="startDelay" value="13000" />
<property name="repeatInterval" value="2500" />
</bean>
I am trying to make them triggered in different time slot. In each scheduledService it referred to a service class with log4j logger instance. There is only one logger defined in log4j2.xml in the fileAppender, so all logging information from the application writing into the safe file.
My question is in such situation is it highly possible that if each logger write into the same logging file generated by Log4J2 then it may cause FileAppender stopped rolling (because of muti threads I/O in the same Log file, then the log file grows crazily with huge file size)? If so how to overcome this issue? Must create different log file for different service class? I wonder if Log4j2 somehow can make above scenario wor
I asked a similar question, but based on the responses, I did a bad job describing what I am after. I have a spring 4 webapp that loads properties from a properties file. We consume those properties both via the "${proper.name"} expressions in spring, as well as by injecting a properties object into some of our classes.
We want to move most of the properties to a database table and make them reloadable. However, a few need to stay in local properties, potentially overriding the database setting. These should also be loaded dynamically after the app is running.
I know that once a particular bean is injected, it won't get reloaded, that doesn't concern me, it's up to that module to handle that. But I am having trouble getting the behavior I want. In particular, I have implemented an AbstractConfiguration from apache commons configuration to get the dual source and overriding I am after. But while it works for injecting the properties object, expressions loaded with "${prop.name}" don't work at all.
How can I get them to work? Did I override the wrong thing? Is it just some config detail?
<bean id="sysProperties" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="databaseConfigurator" />
<property name="targetMethod" value="getProperties"/>
</bean>
<bean id="databaseConfigurator" class="my.util.config.MyDatabaseConfigurator">
<property name="datasource" ref="dataSource" />
<property name="propertyFile" value="/WEB-INF/my.properties" />
<property name="applicationName" value="ThisApp" />
</bean>
<bean id="dbConfigFactory" class="org.apache.commons.configuration.ConfigurationConverter" factory-method="getProperties">
<constructor-arg ref="databaseConfigurator" />
</bean>
I haven't tested this, but I think it might work.
<bean id="sysProperties" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="databaseConfigurator" />
<property name="targetMethod" value="getProperties"/>
</bean>
<bean id="databaseConfigurator" class="my.util.config.MyDatabaseConfigurator">
<property name="datasource" ref="dataSource" />
<property name="propertyFile" value="/WEB-INF/my.properties" />
<property name="applicationName" value="ThisApp" />
</bean>
<bean name="PropertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="CommonsConfigurationFactoryBean"/>
</bean>
<bean name="CommonsConfigurationFactoryBean" class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
<constructor-arg ref="databaseConfigurator"/>
</bean>
I'm using spring's ScheduledTimerTask to schedule some tasks to schedule some tasks.
<bean id="someScheduler" class="com.example.scheduler.SomeScheduler">
</bean>
<bean id="anotherScheduler" class="com.example.scheduler.SomeScheduler">
</bean>
<bean id="someImport" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask" ref="someScheduler" />
</bean>
<bean id="anotherImport" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask" ref="anotherScheduler" />
</bean>
How to make sure anotherScheduler won't execute when someScheduler is being executed?
I would like to configure number of consumers for a single queue in jms template. I tried to implement this: JmsTemplate - define concurrency per queue? but in the ActiveMQQueue is stiil shows 1.
my messanging context:
<bean id="parentContainer" abstract="true"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<bean id="parentContainer" abstract="true"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<bean id="playerStatsListener" parent="parentContainer">
<property name="destination" ref="playerStatsQueue" />
<property name="messageListener" ref="playerStatsService" />
<property name="concurrency" value="100" />
</bean>
<!-- Listeners -->
<bean id="playerStatsService" class="com.XXX.service.PlayerStatsService" />
<!-- Destinations -->
<bean id="playerStatsQueue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="playerStatsQueue" />
another related question: Is there a difference between the "listener" to "messageListener" property?
In general, you can set concurrentConsumers and maxConcurrentConsumers on the DefaultMessageListenerContainer. The concurrency setting gives this as a convenient range.
But according to the docs
Specify concurrency limits via a "lower-upper" String, e.g. "5-10", or
a simple upper limit String, e.g. "10" (the lower limit will be 1 in
this case).
So if you just say concurrency=100, it's still equivalent to 1-100, which would explain why you're seeing 1 consumer.
As of Spring 3.0 the ScheduledTimerTask is deprecated and I can't understand how to upgrade to org.springframework.scheduling.concurrent.
<bean id="timerFactoryBean" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="onlineTimeSchedule" />
</list>
</property>
</bean>
<bean id="onlineTimeSchedule" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask" class="com.example.OnlineTimerTask" />
</property>
<property name="period" value="60000" />
<property name="delay" value="1000" />
</bean>
Where the OnlineTimerTask extends java.util.TimerTask. It's simple task which publishes a message to publisher every minute. I checked the documentation, but nothing.. I can't understand which way to use from the concurrent package and which suits the best.
Also I want to turn this xml into #Bean in Java.
EDIT: So I tried to implement the xml with #Bean and #Configuration instead and here is what I got.
#Configuration
public class ContextConfiguration {
#Bean
public ScheduledExecutorFactoryBean scheduledExecutorFactoryBean() {
ScheduledExecutorFactoryBean scheduledFactoryBean = new ScheduledExecutorFactoryBean();
scheduledFactoryBean.setScheduledExecutorTasks(new ScheduledExecutorTask[] {onlineTimeSchedule()});
return scheduledFactoryBean;
}
#Bean
public ScheduledExecutorTask onlineTimeSchedule() {
ScheduledExecutorTask scheduledTask = new ScheduledExecutorTask();
scheduledTask.setDelay(1000);
scheduledTask.setPeriod(60000);
scheduledTask.setRunnable(new OnlineTimerTask());
return scheduledTask;
}
}
Will the code above be correct replacement for xml? Will in my case the setScheduledExecutorTasks work properly? I mean will the referencing to the same bean instance, if onlineTimeSchedule() is called more than once, will work here?
scheduledFactoryBean.setScheduledExecutorTasks(new ScheduledExecutorTask[] {onlineTimeSchedule()});
Use org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean in place of org.springframework.scheduling.timer.TimerFactoryBean and use org.springframework.scheduling.concurrent.ScheduledExecutorTask in place of org.springframework.scheduling.timer.ScheduledTimerTask. You will need to adjust the property names and values as needed but, that should be pretty self evident.
Optionally, you could refactor your com.example.OnlineTimerTask to not extend java.util.TimeTask as the ScheduledTimerTask only requires a runnable.
Spring 4 configuration - Below configuration working after spring migration from 3.2.x to 4.6.x
<bean id="schedulerTask"
class="org.springframework.scheduling.support.MethodInvokingRunnable">
<property name="targetObject" ref="springJmsListnerContainer" />
<property name="targetMethod" value="execute" />
</bean>
<bean id="timerTask" class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
<property name="runnable" ref="schedulerTask" />
<property name="delay" value="100" />
<property name="period" value="60000" />
</bean>
<bean class="org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean">
<property name="scheduledExecutorTasks">
<list>
<ref bean="timerTask" />
</list>
</property>
</bean>
The answer is - add one "runnable" field
<bean id="scheduledExecutorTask"
class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
<!-- wait 10 milli seconds before starting repeated execution -->
<property name="delay">
<value>10</value>
</property>
<!-- run every 1 second -->
<property name="period">
<value>1000</value>
</property>
<property name="runnable">
<ref bean="checkInvokingTask"/>
</property>
</bean>