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 ?
Related
I am using Weblogic 10.3, Spring 2.0,Oracle 11g. When trying to use the 'threadpoolexecutor' future task (async resp), I am getting the following exception in waiting for asynchronous response where as the bean executed by thread pool executor is 'prototype'
Note: when I am using Spring's ClassPathXmlApplicationContext to get the bean I am not getting the exception, which is not a preferred way to get beans as it loads all the beans again.
I have tried springContextAware ,ApplicationObjectSupport; those also didn't work for me.
- Error:
]", which is more than the configured time (StuckThreadMaxTime) of "600" seconds. Stack trace:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811)
java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:969)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1281)
java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:218)
The bean definition I have is
<bean id="PtTaskExecutor"
class="java.util.concurrent.ThreadPoolExecutor">
<constructor-arg index="0" value="1"/> <!-- corePoolSize -->
<constructor-arg index="1" value="3"/> <!-- maximumPoolSize -->
<constructor-arg index="2" type="long" value="180"/><!-- 3 minutes -->
<!-- keepAliveTime -->
<constructor-arg index="3" type="java.util.concurrent.TimeUnit">
<!-- the time unit for the keepAliveTime argument -->
<util:constant static-field="java.util.concurrent.TimeUnit.SECONDS"/>
</constructor-arg>
<constructor-arg index="4" type="java.util.concurrent.BlockingQueue">
<!-- the queue for holding tasks before they are executed -->
<bean name="LinkedBlockingQueue" class="java.util.concurrent.LinkedBlockingQueue">
<constructor-arg index="0" type="int" value="3"/> <!-- capacity -->
</bean>
</constructor-arg>
<constructor-arg index="5" type="java.util.concurrent.RejectedExecutionHandler">
<!--Execute with caller threads if queue is full -->
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
</constructor-arg>
</bean>
<bean id="xTask" class="***.****.*.*.*.*.XTask" scope="prototype">
<property name="XDao" ref="XDao" />
<property name="transactionTemplate" ref="transactionTemplate"/>
</bean>
-----The code part
Future<YResponseBean[]> responseArr = pTaskExecutor
.submit(xTask);
responseMap.put(i, responseArr);
then the error is from here
for (Integer i : keySet) {
// Waits for the thread response
responses[i] = responseMap.get(i).get()[0];
}
I have tried with lazy-init=true also on threadpoolexecutor, no luck.
The issue isn't with anything coming from java.util.concurrent or weblogic. What weblogic is telling you is that one of its registered threads has been waiting longer then 10 minutes for the get() to return.
So why hasn't it returned? That is because the Callable you submitted has not yet returned. You should check the callable you submit to the executor and find out why that is still in the call() method.
For instance, if I write something like
Weblogic-Thread-1
Future f= e.submit(new Callable(){
public Object call(){
Thread.sleep(700000);
return null;
}
});
Weblogic-Thread-2
f.get(); //will sit here and suspend for 700 seconds
So you need to see why the task you submitted has not yet completed.
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.
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