我正在使用以下代码安排工作。
@Controller
@RequestMapping("VIEW")
public class MyController {
@RenderMapping
public String defaultView() {
try {
String cronText = "0 30 12 1/1 * ? *";
String description = "Message Scheduler Description";
String destinationName = DestinationNames.SCHEDULER_DISPATCH;
int exceptionsMaxSize = 0;
String portletId = "portletId";
Message message = new Message();
message.put(SchedulerEngine.MESSAGE_LISTENER_CLASS_NAME,SchedulerListener.class.getName());
message.put(SchedulerEngine.PORTLET_ID, portletId);
Trigger trigger = new CronTrigger(SchedulerListener.class.getName(), SchedulerListener.class.getName(), cronText);
SchedulerEngineHelperUtil.schedule(trigger,StorageType.PERSISTED, description, destinationName, message, exceptionsMaxSize);
}catch (SchedulerException e) {
e.printStackTrace();
}
return "view";
}
}
上述代码的问题是调度程序仅在服务器会话之前有效。一旦执行了这个方法,我想在服务器重启后在上述时间触发调度程序。有没有办法在liferay中实现这个?
答案 0 :(得分:1)
这似乎是Liferay调度实施的一个问题。 Quartz正确地存储和恢复您的触发器和作业。但是Liferay没有使用你的MessageListener
作为工作。相反,它会将MessageListener
包裹在MessageSenderJob
中,并会注册您的MessageListener
。
重新启动后仍会触发MessageSenderJob
,它会将您的消息发送到消息总线。但是,如果您在此之前没有注册MessageListener
,那么他们将不会接收该消息。
解决方案:您必须在每次启动时注册MessageListener
。通过再次调用SchedulerEngineHelperUtil.schedule
或通过调用MessageBusUtil.registerMessageListener
来调用@WebListener
public class SchedulerListener implements ServletContextListener, PortalLifecycle, MessageListener {
private SchedulerEventMessageListenerWrapper listenerWrapper;
public void contextInitialized(final ServletContextEvent sce) {
// Wait until the portal is ready
PortalLifecycleUtil.register(this, PortalLifecycle.METHOD_INIT);
}
public void portalInit() {
// Register our listener
listenerWrapper = new SchedulerEventMessageListenerWrapper();
listenerWrapper.setGroupName(getClass().getName());
listenerWrapper.setJobName(getClass().getName());
listenerWrapper.setMessageListener(this);
listenerWrapper.afterPropertiesSet();
MessageBusUtil.registerMessageListener(DestinationNames.SCHEDULER_DISPATCH, listenerWrapper);
}
public void contextDestroyed(final ServletContextEvent event) {
// Unregister
if (listenerWrapper != null) {
MessageBusUtil.unregisterMessageListener(DestinationNames.SCHEDULER_DISPATCH, listenerWrapper);
}
}
public void portalDestroy() {
// Ignore
}
public void receive(final Message message) {
// ... your job code here ...
}
}
。有关注册启动操作的一些选项,请参阅我的问题here。
这是一个示例,以防您想要动态创建触发器(由于UI中的某些操作):
listenerWrapper
如果您希望使用固定触发器,则可以放弃SchedulerEngineHelperUtil.schedule(...)
并将问题中的portalInit()
代码放入StorageType.PERSISTED
。
如果你想知道,{{1}}有什么意义:它是用于执行在服务器关闭时或在服务器停机时刚刚启动时触发的触发器。