openxava / documentation / Spring scheluding in your OpenXava application

Sometimes we need to schedule some tasks to be executed regularly, like importing records from remote database or regularly creating reports and sending them by e-mail. OpenXava doesn't have built in features for scheduling so we need to use something else.

Spring is one of the most popular frameworks on the market, so why not use it for this task?
I will use the latest version of Spring to date which is version 5.

To do this we need to modify our project. I'll use my own project as an example.
From the eagle's view we'll create the following files (the root will be your projects's folder in openxava workspace and my project's name is 'Callcenter'):

/Callcenter/src/bilesuvar/callcenter/scheduled/BusRoutesPump.java
/Callcenter/web/WEB-INF/applicationContext.xml
/Callcenter/web/WEB-INF/listeners.xml

also we need to download the latest version of Spring library and extract the following files into directories:
/Callcenter/lib/spring-aop-5.0.0.RELEASE.jar
/Callcenter/lib/spring-aspects-5.0.0.RELEASE.jar
/Callcenter/lib/spring-beans-5.0.0.RELEASE.jar
/Callcenter/lib/spring-context-5.0.0.RELEASE.jar
/Callcenter/lib/spring-core-5.0.0.RELEASE.jar
/Callcenter/lib/spring-expression-5.0.0.RELEASE.jar
/Callcenter/lib/spring-web-5.0.0.RELEASE.jar

I've found in a hard way that I also have to _manually_ copy all contents from /Callcenter/lib to /Callcenter/web/WEB-INF/lib
because OpenXava workspace built in a way which prevents Eclipse from using 'Deployment Assembly' settings. So when you'll try to 'create War' all your libs wouldn't be automatically copied. Still, I think that it is better to keep all your jars in a separate folder because you can always manually copy
them later. But if you keep them in /web/WEB-INF/lib from the start you can forget which ones are yours and which ones are part of OpenXava.

Now we have to tell Eclipse that we want to include those jars in our project. To do this you have to:
1) Open your project in Eclipse and right click on the project (not workspace!) root, then select 'Properties'
2) Open 'Java Build Path' and click on 'Libraries' tab. Now, using 'Add Jars' button, add all Spring libraries from /lib folder
3) Click on 'Order and Export' tab in the same window and put check mark against every jar you just added.
4) Click on 'Deployment Assembly' on the left side of the window. Click 'Add...' button and from 'Java build path entries' add all Spring jars we just added.
5) Click 'Apply and Close'

Now lets create the first 3 files I mentioned.

Those are the contents of 'BusRoutesPump.java'
package com.bilesuvar.callcenter.scheduled;
 
import org.springframework.scheduling.annotation.Scheduled;
 
import org.springframework.stereotype.Component;
 
@Component("busRoutesPumpService")
public class BusRoutesPump {
 
    public void pump() {
     // Some useful stuff you want to do regularly
    }
 
}

And 'applicationContext.xml'

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task.xsd">
 
    <context:component-scan base-package="com.bilesuvar.callcenter.scheduled" />
 
    <!-- Configure the scheduler -->
    <task:scheduler id="myScheduler"/>
 
    <!-- Configure parameters -->
    <task:scheduled-tasks scheduler="myScheduler">
        <task:scheduled ref="busRoutesPumpService" method="pump" fixed-delay="900000" initial-delay="10000"/>
    </task:scheduled-tasks>
 
</beans>
And 'listeners.xml'

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
Well, that's all.
Better to rebuild your project just to be sure. Press 'Control-B'.
Right click on 'build.xml' file in your project's root and select 'Run as -> Ant build'
And sometimes you need to right click on your Tomcat 7.0 server and select 'Clean Tomcat Work Directory' and 'Clean...'
You know all this shaman's stuff :)