Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the simplest way to execute a Java class every 30 seconds?

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

like image 577
Gandalf StormCrow Avatar asked Mar 19 '10 10:03

Gandalf StormCrow


4 Answers

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>
like image 68
skaffman Avatar answered Nov 13 '22 21:11

skaffman


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

Check this out: Implement @Scheduled in Spring Application

like image 31
sundary Avatar answered Nov 13 '22 20:11

sundary


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.

like image 1
Reverend Gonzo Avatar answered Nov 13 '22 20:11

Reverend Gonzo


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>  
like image 1
Wiretap Avatar answered Nov 13 '22 20:11

Wiretap