我正在使用下面的代码安排作业。
@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";
}
}
上述代码的问题是,调度器仅在服务器会话之前有效。一旦执行了这个方法,我想在提到的时间触发schedulerjob,即使在服务器重启之后也是如此。有没有办法在liferay中实现这一点?
这似乎是Liferay调度的实现中的一个问题。Quartz正在正确存储和恢复触发器和作业。但是Liferay并没有把你的MessageListener
当作工作。相反,它将把你的MessageListener
包装在MessageSenderJob
中,并注册你的MessageListener
。
重启后MessageSenderJobs
仍将被触发,它会将您的消息发送到消息总线。但是,如果您在那之前没有注册您的MessageListener
,他们将无法接收该消息。
解决方案:你必须在每次启动时注册你的MessageListener
。通过调用SchedulerEngineHelperUtil。再次调度,或通过调用MessageBusUtil。registerMessageListener
。有关注册启动操作的一些选项,请参见我的问题。
这里有一个示例,以防您想动态创建触发器(由于UI中的一些操作):
@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 ...
}
}
如果你想有一个固定的触发器代替,你可以删除listenerWrapper
并把你的SchedulerEngineHelperUtil.schedule(...)
代码从你的问题到portalInit()
。
如果你想知道,StorageType有什么意义。持久化
:用于执行在服务器关闭时触发的触发器,或在服务器关闭时刚刚启动的触发器。
我在Spring 3中使用@Scheduled annotation。我需要每周或每两周运行一些任务,所以我使用cron表达式作为参数,例如。 我的问题是,如果我将创建必须每7天运行一次的计划任务,并且在第6天我将重新启动服务器(与战争重新部署),它会重置这个计划任务(我需要再次等待7天)还是它会保存其状态并在第7天触发此任务?
我正在使用 Windows 服务器 2016 数据中心。每当服务器重新启动时,我在任务计划程序中的计划任务总是停止运行。只有在我手动进入应用程序并重新键入我的用户帐户密码后,它才会再次开始工作。这是设置还是条件问题?
我们有一个Java应用程序,它使用Quartz来调度作业。我们使用的quartz版本是Quartz-2.2.1。quartz配置使用JDBC作业存储。 以下是系统中发生的事件序列: null 我的问题是,当quartz调度器启动时,数据库已经启动--那么为什么它会抱怨连接已经关闭?我知道它在内部使用c3p0连接池,应用程序在签出时不验证连接。c3p0连接池是否关闭quartz调度程序正在使用的连接
我有一个带有控制器的Spring portlet,其结构如下。 这是我之前问题的变体,我没有得到任何答案。 我们有时会重启服务器。我们希望避免外部人员再次手动执行调度。由于它目前是一个portlet,因此有必要呈现视图,以便执行此代码。有没有办法在liferay服务器启动后立即自动执行此调度代码?
我在我的Windows 2008 R2机器中安排了一个任务,但它未能触发日志中的以下错误(事件日志)。 错误: 任务计划程序无法启动用户“SAFFRON3\cb_admin”的“\Hyatt_International_Distribution”任务。其他数据:错误值:2147943645。 任务计划程序启动任务引擎""进程失败,原因是"LUAIsUpatedToken"中发生错误。命令="tas
我在我的Windows 2008 R2服务器上使用任务计划程序创建了一个任务。它会打开一个. bat文件。这个bat没有错误,工作正常。如果我开始任务(即单击运行),它会执行bat文件。从现在开始,它应该每隔x分钟重复一次(目前设置为1分钟),但它没有。我尝试了很多,几乎改变了每个属性,但它仍然不会重复执行我的bat文件。 我已经阅读了不同的问题和答案,但没有任何效果。 有人知道我做错了什么吗?