How to create scheduler in portlet
Sometimes you have a need to create a task that is being executed periodically. You can use scheduler (based on Quartz API ) that is integrated with Liferay. There are 3 steps to do this.
1. Write a class the implements the com.liferay.portal.job.Scheduler interface
2. Write a class that contains actual task that needs to be executed. This class must implements com.liferay.portal.job.IntervalJob interface
3. Register your scheduler in liferay-portlet-ext.xml ( if you use ext environment )
Now let’s go to the details.
1. Write a class that implements Scheduler interface.
package com.ext.portlet.onlineproject.job;
import com.liferay.portal.job.JobScheduler;
import org.quartz.SchedulerException;
public class Scheduler implements com.liferay.portal.job.Scheduler {
public void schedule() throws SchedulerException {
JobScheduler.schedule(new SyncDataJob());
}
}
2. Write the class that contains actual task. On this example, our actual task would be only to write ‘THIS IS THE ACTUAL TASK!” to console. This task would be executed every minute.
package com.ext.portlet.onlineproject.job;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import com.liferay.portal.job.IntervalJob;
import com.liferay.util.Time;
public class SyncDataJob implements IntervalJob{
public SyncDataJob() {
_interval = Time.MINUTE;
}
public long getInterval() {
return _interval;
}
public void execute(JobExecutionContext context)
throws JobExecutionException {
try {
System.out.println("THIS IS THE ACTUAL TASK!");
}
catch (Exception e) {
_log.error(e);
}
}
private static Log _log = LogFactory.getLog(SyncDataJob.class);
private long _interval;
}
If you want to change the interval, you can just change this line :
public SyncDataJob() {
_interval = Time.MINUTE;
}
Change Time.MINUTE to Time.HOUR or Time.DAY.
3. Register in liferay-portlet-ext.xml.
<portlet> <portlet-name>Online_Project</portlet-name> <struts-path>ext/onlineproject</struts-path> <scheduler-class>com.ext.portlet.onlineproject.job.Scheduler</scheduler-class> <use-default-template>false</use-default-template> </portlet>
Done. ( This article tested on Liferay 4.3.3 )
9 comments so far
Leave a reply
Hi,
I read your post, but, i have some problem to implement Scheduler on my portlet.
Could you help me ?
http://www.liferay.com/web/guest/community/forums/-/message_boards/message/935043
Thank’s.
Mickaël.
Hi Mickaël,
Have you registered the scheduler on liferay-portlet-ext.xml ( see step no. 3 ) ? And please check portal-ext.properties in case one of your team member disable the scheduler.
scheduler.enabled=true
Hi Mick!
I need to create a process that past a while updating the information of a portlet connecting to a database! I thought for this use quartz!
I wanted to know if it is also possible that starting a process that attends an incoming message and update the info into a portlet.
How can I do that?
Thanks .-
Hi –
I’ve done as you suggested for 5.1.2, and had to make some modifications to implement the latest interface refactoring.
For now, I’m just trying to get liferay to acknowledge, thru quartz, the existence of my portlet, and I’m close. The error I get is:
04:26:42,781 WARN [PortletLocalServiceImpl:283] Portlet with the name Importer is described in liferay-portlet.xml but does not have a matching entry in portlet.xmlI tried updated portlet-ext.xml, but it just threw more NPE’s. It could be that I didn’t have the correct tags and entries?
Thoughts and suggestions are appreciated.
-Neil
Hi Neil,
I think you should register your scheduler in liferay-portlet-ext.xml. And don’t forget to use the same portlet name for your portlet on liferay-portlet-ext.xml and on portlet-ext.xml. Please check the content of liferay-portlet-ext.xml on my writing, and this is the coresponding entry on portlet-ext.xml :
Thanks, much – it worked!
One interesting refactoring to your implementation for 5.1.2: the schedule method needs to invoke the JobSchedulerUtil to get an instance of the jobScheduler, instead of invoking the static method.
public void schedule() {
JobScheduler jobScheduler = JobSchedulerUtil.getJobScheduler();
jobScheduler.schedule(new SyncDataJob());
}
I appreciate the timely help.
-Neil
Hello,
Thanks for the information on Scheduler in Liferay.
I tried the same & I am facing an issue.
I am using EXT environment (Liferay-5.2.2). I have a portlet by name ‘Registration’ and I followed the steps described below to test the same.
This is the entry I gave in liferay-portal-ext.xml
Registration
ext/registration
com.ext.portlet.registration.job.Scheduler
false
And did everything described above but when I start my server I get the following ClassCastException
Starting Liferay Portal Standard Edition 5.2.2 (Augustine / Build 5202 / February 20, 2009)
16:49:06,377 ERROR [MainServlet:336] java.lang.ClassCastException: com.ext.portlet.registration.job.Scheduler
java.lang.ClassCastException: com.ext.portlet.registration.job.Scheduler
at com.liferay.portal.servlet.MainServlet.init(MainServlet.java:328)
at javax.servlet.GenericServlet.init(GenericServlet.java:212)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1172)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:992)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4058)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4371)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:627)
at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:553)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:488)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Schedule works fine, but I want it to fire on a date/time, not on an interval. How do I do that?
I have written a simple scheduler by following the blog @
Is there any way i can change the scheduler job interval time afer server startup.
Through configuration section in my custom portlet i tried to change the schedule job interval BUT i was not able to see reflected time in my scheduled job execution