12

I've been reading about java/spring/hibernate and worked trough a "dummy" examples so I told my friend to recommend something a bit harder for me, and now I'm stuck.. here is the simplest class I could think of

package spring.com.practice;

public class Pitcher {

    private String shout;

    public String getShout() {
        return shout;
    }

    public void setShout(String shout) {
        this.shout = shout;
    }

    public void voice()
    {
        System.out.println(getShout());
    }

}

What is the most simple way to print out something by calling metod voice() from spring beans, and do it repeadatly every 30 seconds lets say, here is what I've got so far :

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
    <property name="jobDetail" ref="jobSchedulerDetail" />
    <property name="startDelay" value="0" />
    <property name="repeatInterval" value="30" />
</bean>


<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="schedulerName" value="pitcherScheduler" />
    <property name="triggers">
        <list>
            <ref bean="simpleTrigger" />
        </list>
    </property>
</bean>
 <bean id="pitcher" class="spring.com.practice.Pitcher">
 <property name="shout" value="I started executing..."></property>
 </bean>

And yes I'm trying to run this on Jboss 5, I'm building a project with maven.

I got some suggestions and my application context now looks like :

<?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:sched="http://www.springinaction.com/schema/sched"
   xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springinaction.com/schema/sched
       http://www.springinaction.com/schema/sched-1.0.xsd"
       default-lazy-init="true">

   <bean id="stuffDoer" class="spring.com.practice">
   <property name="shout" value="I'm executing"/>
   </bean>

  <sched:timer-job
       target-bean="stuffDoer"
       target-method="voice"
       interval="5000" 
       start-delay="1000"
       repeat-count="10" />

</beans>

Here is my web.xml :

<web-app id="simple-webapp" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>spring app</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/conf/applicationContext.xml
</param-value>
    </context-param>
    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>/WEB-INF/log4j.properties</param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.util.Log4jConfigListener
</listener-class>
    </listener>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
</listener-class>
    </listener>
</web-app>

Now I get this exeption :

12:35:51,657 ERROR [01-SNAPSHOT]] Error configuring application listener of class org.springframework.web.context.ContextLoaderListener
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener

I didn't realize executing something like hello world every 30 sec would be this complicated

Neil McGuigan
  • 46,580
  • 12
  • 123
  • 152
Gandalf StormCrow
  • 25,788
  • 70
  • 174
  • 263

5 Answers5

28

I wouldn't bother with Quartz, it's overkill for something this simple. Java5 comes with its own scheduler, and it's good enough.

Pre-Spring 3, this is was the easiest approach:

<bean class="org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean">
    <property name="scheduledExecutorTasks">
        <list>
            <bean class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
                <property name="period" value="30000"/>
                <property name="runnable">
                    <bean class="org.springframework.scheduling.support.MethodInvokingRunnable">
                        <property name="targetObject" ref="pitcher"/>
                        <property name="targetMethod" value="voice"/>
                    </bean>
                </property>
            </bean>
        </list>
    </property>
</bean>

With Spring 3, it can be ridiculously easy:

@Scheduled(fixedRate=30000)
public void voice() {
    System.out.println(getShout());
}

and

<beans xmlns="http://www.springframework.org/schema/beans"
           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/task http://www.springframework.org/schema/task/spring-task.xsd
           "> 

  <bean id="pitcher" class="spring.com.practice.Pitcher">
     <property name="shout" value="I started executing..."></property>
  </bean>

  <task:annotation-driven/>

</beans>
skaffman
  • 398,947
  • 96
  • 818
  • 769
  • 2
    That `@Scheduled` annotation looks really nice. – BalusC Mar 19 '10 at 12:32
  • @skaffman thank you for your response, I'll try that now, the thing is I want to do something more complicated so I want to start from bottom up. `I want to create 2 objects that send messages to each other, one to greet other to respond trough JMS messaging on JBOSS 5, and I want this done every 30 seconds.` So first thing to consider would be the executing task every 30 seconds and then onwards .. – Gandalf StormCrow Mar 19 '10 at 12:36
  • @skaffman Great answer, I tried it both ways and its working .. w00w tnx – Gandalf StormCrow Mar 19 '10 at 13:10
  • @BalusC: It is quite tasty, I agree, but in practice you want to make the period configurable, and that's where the annotation doesn't work. – skaffman Mar 19 '10 at 13:46
  • Hello skaffman, could you please explain how ScheduledExecutorFactoryBean is used then ? Or please take a look at this question I can't figure out http://stackoverflow.com/questions/3021766/spring-scheduled-threadpool-running-threads-with-parameters-supplied-different ... You seem to have a strong grasp of this – lisak Jun 11 '10 at 15:17
2

With Spring 3, you can quickly use @Scheduled and @Async !

Check this out: Implement @Scheduled in Spring Application

Guido
  • 46,642
  • 28
  • 120
  • 174
sundary
  • 21
  • 1
1

It looks complicated, but that really is the best way to do that. You can configure it external to the application, and let spring/quartz handle execution.

This is especially useful when the method you need to call is a transaction-enabled service call.

Reverend Gonzo
  • 39,701
  • 6
  • 59
  • 77
  • @Reverend Gonzo obviously there is something wrong with this .. I get no exeptions, and yet the quartz doesn't execute, copied war to jboss dir .. and still nothing, I created simple webapp hello world to chk is my jboss configured properly, yes it is. – Gandalf StormCrow Mar 19 '10 at 10:13
1

I have something similar but using the QuartzConnector class in mule, which runs every 20 seconds. See example. The other way would be to use the cron type time entry see Quartz Cron

    <endpoint name="poller" address="quartz://poller1" type="sender" connector="QuartzConnector">
      <properties>
        <property name="repeatInterval" value="20000"/>
        <property name="payloadClassName" value="org.jdom.Document" />
        <property name="startDelay" value="10000"/>                
      </properties>
    </endpoint>  
Wiretap
  • 771
  • 2
  • 9
  • 13
  • @Wiretap thank you I'm really trying to learn spring and as much as possible about it, so I'd like to use springs quartz – Gandalf StormCrow Mar 19 '10 at 10:29
  • Looks like this may be useful, as sounds like similar situation http://www.jroller.com/habuma/entry/a_funny_thing_happened_while – Wiretap Mar 19 '10 at 10:52
  • It appears that up to now I didn't link my application context with web.xml here is the error I get now `12:35:51,657 ERROR [01-SNAPSHOT]] Error configuring application listener of class org.springframework.web.context.ContextLoaderListener java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener` I'll update my question with appcontext – Gandalf StormCrow Mar 19 '10 at 11:48
0

you can use scheduled task

<bean id="EmptyScopesRemover" class="com.atypon.pagebuilder.core.tasks.impl.EmptyScopesRemoverImpl"/>

<task:scheduled-tasks>
    <task:scheduled ref="EmptyScopesRemover" method="remove" cron="0 */1 * * * *"/>
</task:scheduled-tasks>

here is a video https://www.youtube.com/watch?v=mt5R_KBlhTU

and you can check this answer to corn values https://stackoverflow.com/a/32521238/4251431

Basheer AL-MOMANI
  • 14,473
  • 9
  • 96
  • 92