当前位置: 首页 > 知识库问答 >
问题:

服务器重启后Liferay计划程序不工作

唐昊焜
2023-03-14

我正在使用下面的代码安排作业。

@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中实现这一点?

共有1个答案

狄珂
2023-03-14

这似乎是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文件。 我已经阅读了不同的问题和答案,但没有任何效果。 有人知道我做错了什么吗?