Reputation: 1363
I am running Spring 3.2.3.RELEASE and I have several methods within @Service decorated classes that are Scheduled tasks and thus decorated with the @Scheduled annotation.
All the Spring beans are detected and instantiated within the container, however the @Scheduled annotations are never invoked.
I have several application contexts, but the main file is described below as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<import resource="classpath:core-properties.xml" />
<import resource="classpath:core-datasource.xml" />
<import resource="classpath:core-task-scheduler.xml" />
<context:component-scan base-package="com.atlaschase.project.core">
<context:exclude-filter type="regex"
expression="com.atlaschase.project.core.services.jms.*" />
<context:exclude-filter type="regex"
expression="com.atlaschase.project.core.services.processor.*" />
<context:exclude-filter type="regex"
expression="com.atlaschase.project.core.services.remote.*" />
<context:exclude-filter type="regex"
expression="com.atlaschase.project.core.bootstrap.populators.*" />
</context:component-scan>
<bean id="bufferPopulator" class="com.atlaschase.project.core.services.jms.buffer.BufferPopulator"/>
<bean id="eventBuffer" class="com.atlaschase.project.core.services.jms.buffer.EventBuffer"/>
<bean id="processorEventHandler" class="com.atlaschase.project.core.services.jms.buffer.ProcessorEventHandler"/>
The other important file is imported as "core-task-scheduler.xml". This is configured as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="1"/>
<task:scheduler id="myScheduler" pool-size="5"/>
</beans>
Originally, the executor reference (above) was defined in the main application context, but I split this out as an import after reading that other similar problems had been solved in this way. Unfortunately this has not helped. I have also moved the import declarations around, but this seems to have no effect.
Declaring Scheduled methods in the Spring Application Context directly works fine - however I am very keen to use annotations.
Here is the annotated class:
**
* Service that batches the saving of position updates into a periodically executed
* process.
*/
@Service
public class PositionAggregatorService {
static Logger logger = Logger.getLogger(AircraftPositionAggregatorService.class);
// The service will not execute within 1 minute of a previous batch attempt.
// This paramater is updated by a message from another node indicating that
// they are commencing a batch save of position updates.
private DateTime blockingTime;
private Map<Long, List<Position>> positions;
@Autowired
private PositionDao positionDao;
@Autowired
private InternalPublisher internalEventPublisher;
@PostConstruct
private void initialise(){
positions = new ConcurrentHashMap<Long, List<Position>>();
}
/*
* Scheduled to execute every 10 minutes as long current time is not
* before the blocking time threshold.
*
* */
@Scheduled(fixedRate=6000)
public void batchSavePositionUpdates(){
if(blockingTime != null){
if(DateTime.now(DateTimeZone.UTC).isBefore(blockingTime)){
return;
}
}
PositionPersistStartedNotification started = new PositionPersistStartedNotification(DateTime.now(DateTimeZone.UTC), DateTime.now(DateTimeZone.UTC).plusMinutes(2));
internalEventPublisher.publishPositionPersistStartedNotification(started);
DateTime mostRecentUpdateTime = null;
List<Position> positionsToSave = new ArrayList<Position>();
for(Long flightId : positions.keySet()){
List<Position> positionList = positions.get(flightId);
for(Position position : positionList){
if(mostRecentUpdateTime == null){
mostRecentUpdateTime = new DateTime(position.getTime());
}
else{
DateTime positionTime = new DateTime(position.getTime());
if(positionTime.isAfter(mostRecentUpdateTime)){
mostRecentUpdateTime = positionTime;
}
}
positionsToSave.add(position);
}
}
Boolean successfulSave = false;
try{
positionDao.save(positionsToSave);
successfulSave = true;
logger.info(positionsToSave.size() + " Position Updates saved successfully");
}catch(Exception exception){
logger.error("Failed to persist latest position updates to database");
logger.error(exception);
}
if(successfulSave){
removeSavedPositions(mostRecentUpdateTime);
PositionPersistEndedNotification ended = new PositionPersistEndedNotification(DateTime.now(DateTimeZone.UTC), mostRecentUpdateTime);
internalEventPublisher.publishPositionPersistEndedNotification(ended);
}
}
}
Any help would be appreciated.
Upvotes: 0
Views: 821
Reputation: 1363
The application was being started by listening for the context to be loaded and then executing a method upon the ContextRefreshedEvent.
When I removed this ApplicationEventListener from the application and simply invoked a public method on the bean to start the service (instead of relying in the ApplicationEventListener) - the application then started normally with all @Scheduled annotations working as expected.
Upvotes: 0
Reputation: 21391
Is the Spring context loaded successfully in runtime? I see you have some inconsistencies in namespace definitions where various versions co-exist in the xsd (3.0 and 3.2). Can you try having consistently the same version in these namespaces and try again?
Upvotes: 2