1

I'm very new to Quartz, but know 3 simple things which you have to have in order to make it work. These are jobs, triggers and scheduler.

Now, in our domino application we have to use it for refreshing a token.

I've created 3 basic classes for it.

The job:

public class RefreshEGRZTokenJob implements Job 
{
    public void execute(JobExecutionContext arg0) throws JobExecutionException 
    {
        System.out.println("stub for refreshing a token");  
    }
}

The trigger and something like main:

public class RefreshEGRZTokenExecutor
{
    private static String REFRESH_TOKEN_JOB = "refreshTokenJob";

    public static void executeAndScheduleRefreshToken(int timeInSeconds) throws SchedulerException 
    {
        JobDetail job = JobBuilder.newJob(RefreshEGRZTokenJob.class)
        .withIdentity(REFRESH_TOKEN_JOB).build();

        Trigger trigger =  TriggerBuilder
        .newTrigger()
        .withIdentity(REFRESH_TOKEN_JOB)
        .withSchedule(
            SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(timeInSeconds).repeatForever())
        .build();

        QuartzScheduler.getInstance().scheduleJob(job, trigger);
    }

    public static void pauseScheduler() throws SchedulerException 
    {
        QuartzScheduler.getInstance().standby();
    }
}

And the scheduler:

public final class QuartzScheduler 
{
    private static Scheduler quartzSchedulerInstance;

    public static Scheduler getInstance() throws SchedulerException 
    {
        if (quartzSchedulerInstance == null) 
        {
            Scheduler scheduler = new StdSchedulerFactory().getScheduler();
            scheduler.start();
            quartzSchedulerInstance = scheduler;
        }
        return quartzSchedulerInstance;
    }
}

The call I make is from a button (in production it'll execute shortly after the user authorized)

 <xp:eventHandler event="onclick" submit="true"
    refreshMode="complete">
    <xp:this.action><![CDATA[#{javascript:      
    ru.lanit.egrz.scheduler.RefreshEGRZTokenExecutor.executeAndScheduleRefreshToken(30);


    }]]>
    </xp:this.action>

 </xp:eventHandler>

Well, quartz scheduler is initilized and the job is set but doesn't execute the job (I know this because if I press the same button twice, it'll give me an exeption that the job already exists).

I guess Domino's JVM doesn't let the scheduler run indefinitely.

The reason why I don't use standard IBM's agent is simple - it doesn't allow to use Java code in Code section. You have to either import and duplicate everything you have so far or to compile it into jar and import. But if you decide to change anything in your sources you'll have to recompile the entire jar (with new source code) and re-import that.

Has anybody integrated Domino JVM and Quartz?

If so, please tell me the best practices and how to make it work.

Thanks in advance.

Rus9Mus9
  • 160
  • 1
  • 17
  • No clue about Quartz, but is this in XPages? – D.Bugger Dec 01 '19 at 23:36
  • Yes, basically it's more related to JVM running the server. It might be called from a XPage (scheduling a job) or automatically (doing some job every something) The thing is to integrate these two together – Rus9Mus9 Dec 02 '19 at 06:29
  • To my understanding, there are two separate JVMs: one for a Java agent and one for the HTTP task and XPages. Now, this Quartz Scheduler, is it supposed to be started once for all users, or once per user session? Maybe you should look at how a Managed Java Bean can be started and run in either application scope or session scope. Where do you put the code for your event handler, and how is it executed? – D.Bugger Dec 02 '19 at 07:20
  • It's supposed to run as soon as any user logins to the system. (for refreshing a token, we use it for integration with another system). There's another job for the scheduler - it'll create a job for sending data to the system (because data to be sent might often exceed 2GB, it doesn't make sense to execute it when the user presses the button right away and make their client time-out). Initiation of this case is up to the user pressing the button but the job will execute only after some time (night preferably) – Rus9Mus9 Dec 02 '19 at 07:38
  • Better wait for someone more qualified to answer your question. My hunch is that you could do this using an OSGI plugin, see also: https://www.slideshare.net/fiorep/domino-osgi-development – D.Bugger Dec 02 '19 at 11:05
  • You need Threads not schedulers here – stwissel Dec 04 '19 at 11:45
  • I have quickly created an OSGi plugin which implements Quartz, works like a charme. – Sven Hasselbach Dec 05 '19 at 09:43
  • Could you please submit your answer? Thank you – Rus9Mus9 Dec 05 '19 at 10:36

2 Answers2

1

You have a set of hurdles to overcome here:

  1. Your scheduler needs to run "forever", so you need to run it from where it doesn't die. That place is an OSGi plugin. The place for your scheduler would be the activator class. something along those lines:
import java.util.logging.Logger;

import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator extends Plugin implements BundleActivator {

 @Override
    public void start(final BundleContext context) throws Exception {
       // Here you start your scheduler
    }

}
  1. You need to call it from somewhere (and that shouldn't be SSJS). So you would create a managed bean that can access the plugins activator. Put the bean code into the plug-in. Once you have defined it you can call the bean method in your button

  2. Your scheduler runs a token refresh. What is supposed to happen with the refreshed token?


Having said all this. You probably can get away with a much simpler solution (unless your token needs millisecond precision):

  • Create a managed bean for the session context (Each bean is individually instantiated per user).
  • In the bean have a method you will call from your button (or elsewhere) that kicks of a new thread. That thread sleeps for a while before you execute again. Check for a property of being shut down, so you can terminate gracefully.

Hope that helps

stwissel
  • 20,110
  • 6
  • 54
  • 101
  • Hello, thank you very much for your answer and support! For some time I thought that nobody knows the answer. Well, first of all I don't quite need millisecond precision, but the token might be refreshing during the night (when the sessionScope is gone, obv). There are other cases such as sending the data to the system B (which may exceed 2GB, there are files chunked by 1MB). That's why I found Quartz quite handy. I'll try your solution and give you feedback as soon as I can. Thank you very much! – Rus9Mus9 Dec 04 '19 at 12:06
  • // Here you start my scheduler. So, only starting? Scheduling, creating triggers, jobs. etc may be just as other ordinary normal Java classes? I suppose that the jobs which I've created don't die unless I restart the server. I figured it out because when I click the same button twice (executeAndScheduleRefreshToken from RefreshEGRZTokenExecutor class) it gives me an exception that the job already exists – Rus9Mus9 Dec 04 '19 at 12:14
1

I have created a plugin, you can find it here: https://github.com/hasselbach/domino-quartz

The feature project and the updatesite project are missing.

You have to install the plugin on the server and in the DDE and activate it in your XPages application.

Sven Hasselbach
  • 10,455
  • 1
  • 18
  • 26
  • Well, thank you very much for your answer, though it didn't help, I see how much you wanted to help me, put so much effort. Now, I'm giving up. It's just insane, this plugin stuff. As a programmer, I just want to import a required jar and simply make this stuff work. However, in Domino everything seems to be pain in the arse. Really crazy. It's just like if I happened to program in IDEA and import some components which would work and compile only inside IDEA, but not in the web. Anyway, thanks for your time. – Rus9Mus9 Dec 07 '19 at 11:59
  • I've accepted this answer because there might be some ppl who know Domino administration very well, and can make this plugin work in their app – Rus9Mus9 Dec 07 '19 at 12:03
  • It is complicated, but brilliant, because it solves dependency management and helps a lot with maintaining a huge amount of different applications. If you understand it, you will love it. Even as a programmer. – Sven Hasselbach Dec 09 '19 at 10:05
  • And it took me just a few minutes to implement it, so my effort is negligible ;-) – Sven Hasselbach Dec 09 '19 at 10:07