I’m trying to create a task scheduler. I use Quartz. I followed this example.
I make the dependence in maven (tested 2.2.1 and 2.2.2) and my class HelloJob implements Job.
I have
public class HelloJob implements Job{
public void execute(JobExecutionContext context) throws JobExecutionException {
// Say Hello to the World and display the date/time
System.out.println("Hello World! - " + new Date());
JobDetail job = newJob(HelloJob.class)
.withIdentity("job1", "group1")
.build();
}
}
But I have the message:
The method newJob(Class<HelloJob>) is undefined for the type HelloJob
I tried to put the JobDetail declaration in my SimpleExample class, but the same error appears...
The method newJob is defined in org.quartz.JobBuilder as static. Add an static import in your class:
import static org.quartz.JobBuilder.*;
Related
i'm trying to using cron job to give information about connection to server, but i allready tried any method and when i'm running java file as application my cron job script is not running at all.
#Component
public class checkData {
#Scheduled(cron = "0/10 * * * * *")
public void test(){
System.out.println("test cron job");
}
and i tried to running it in another class
#SpringBootApplication
#EnableScheduling
#Configuration
#ConditionalOnProperty("spring.enable.scheduling")
public class test{
public static void main(String args[]) throws JRException {
SpringApplication.run(test.class);
}
}
}
when i'm running test class as java application it's get error java class not found. is there something wrong in my script ? thank's
I am using quartz in my apache isis project for scheduling. I have a class MyJob which implements org.quartz.Job and it has method execute which is called when scheduler triggers at given time.
My problem is, I have a class DemoService and it has a method showDemo() which I want to call from the execute method.
But when the scheduler runs, it throws Null Pointer Exception at demoService.showDemo().
I have not been able to inject any service in that class. It always gives NPE. How can I inject a service into the MyJob class?
Here is the code:-
public class MyJob implements Job {
#Inject
DemoService demoService;
public MyJob() {
}
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
demoService.showDemo();
}
}
The easiest approach is to put the logic you want to run in a subclass of AbstractIsisSessionTemplate, and then instantiate and execute it from your quartz job.
This technique is used by the Incode Platform's quartz job to run background commands, see here; the quartz module shows this from the quartz perspective (which I think you already have figured out).
HTH
Dan
Try this NullPointerException while deploying Quartz in Spring Boot
You need to use SpringBeanJobFactory to create Job with Spring's autowired beans.
class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private transient AutowireCapableBeanFactory beanFactory;
public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory();
}
#Override
public Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job); //the magic is done here
return job;
}
}
And then when you do
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
scheduler = schedFact.getScheduler();
AutowiringSpringBeanJobFactory autowiringSpringBeanJobFactory = new AutowiringSpringBeanJobFactory();
autowiringSpringBeanJobFactory.setApplicationContext(applicationContext);
scheduler.setJobFactory(autowiringSpringBeanJobFactory);
package org.quartz;
import org.quartz.Scheduler;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Trigger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.JobBuilder.*;
import static org.quartz.TriggerBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*;
import static org.quartz.CronScheduleBuilder.*;
import static org.quartz.CalendarIntervalScheduleBuilder.*;
import static org.quartz.DateBuilder.*;
class myJob implements Job {
public void execute(JobExecutionContext context)
throws JobExecutionException
{
System.out.println("Hello! HelloJob is executing.");
}
}
public class schedule{
public static void main(String args[]) throws Exception{
System.out.println("Java working");
try {
// Grab the Scheduler instance from the Factory
JobKey jobKeyA = new JobKey("myJob", "group1");
JobDetail jobA = JobBuilder.newJob(myJob.class)
.withIdentity(jobKeyA).build();
// Trigger the job to run now, and then every 40 seconds
Trigger trigger1 = TriggerBuilder
.newTrigger()
.withIdentity("dummyTriggerName1", "group1")
.withSchedule(
CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
.build();
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
// and start it off
scheduler.start();
// Tell quartz to schedule the job using our trigger
scheduler.scheduleJob(jobA, trigger1);
} catch (SchedulerException se) {
se.printStackTrace();
}
}
}
And I am getting an error of instantiating job and then obviously All triggers of Job set to ERROR state.
What is the reason?
and please help it is very important.
provide me the answer.
Error
[ERROR] 28 Dec 03:03:30.008 PM
DefaultQuartzScheduler_QuartzSchedulerThread
[org.quartz.core.ErrorLogger]
An error occured instantiating job to be executed. job= 'group1.myJob'
org.quartz.SchedulerException: Problem instantiating class
'org.quartz.myJob' [See nested exception:
java.lang.IllegalAccessException: Class
org.quartz.simpl.SimpleJobFactory can not access a member of class
org.quartz.myJob with modifiers ""]
at org.quartz.simpl.SimpleJobFactory.newJob(SimpleJobFactory.java:58)
at org.quartz.simpl.PropertySettingJobFactory.newJob(PropertySettingJobFactory.java:69)
at org.quartz.core.JobRunShell.initialize(JobRunShell.java:127)
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:375)
Caused by: java.lang.IllegalAccessException: Class
org.quartz.simpl.SimpleJobFactory can not access a member of class
org.quartz.myJob with modifiers ""
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.Class.newInstance(Class.java:436)
at org.quartz.simpl.SimpleJobFactory.newJob(SimpleJobFactory.java:56)
... 3 more [INFO] 28 Dec 03:03:30.013 PM
DefaultQuartzScheduler_QuartzSchedulerThread
[org.quartz.simpl.RAMJobStore]
All triggers of Job group1.myJob set to ERROR state.
Your job class has to be public. Otherwise, the JobBuilder can not read it.
public class myJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Hello! HelloJob is executing.");
}
}
Class should be public class
Default constructor should be public
Improvement on top of the solution above. The class can be marked with static keyword to improve the efficiency. The job will be created each time when the scheduled slot occured.
public static class MyJob implements Job {
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("My job is called");
}
}
Anything wrong in this program ?
I am getting nullPointerException while calling web service in play framework in version 2.4.3.
package com.enkindle.box;
import javax.inject.Inject;
import play.libs.ws.WSClient;
/**
* #author thirumal
*
*/
public class Sample {
#Inject WSClient ws;
public static void main(String[] args) {
Sample sample = new Sample();
sample.callAPI();
}
public void callAPI() {
ws.url("www.thomas-bayer.com/sqlrest/CUSTOMER/").get();
}
}
The issue is that your Sample class is not available within the context of your dependency injection - I'm assuming Guice. There are a couple ways to tackle this but the easiest is to create a Sample interface and bind its implementation, SampleImpl, using Guice so that it will be available for injected dependencies. I'm going to assume that this gets spawned from a controller, so you could inject Sample into your controller and hit the callApi() method from there.
Controller:
public class SampleController extends Controller {
#Inject Sample sample;
public Promise<Result> apiCall() {
sample.callApi();
return promise(() -> ok());
}
}
Interface:
#ImplementedBy(SampleImpl.class)
public interface Sample {
public void callApi();
}
And the interface implementation:
public class SampleImpl implements Sample {
#Inject WSClient ws;
#Override
public void callApi() {
// ws should not be null
ws.url("www.thomas-bayer.com/sqlrest/CUSTOMER/").get();
}
}
Reference docs: https://www.playframework.com/documentation/2.4.x/JavaDependencyInjection#Binding-annotations
I am using Dagger 2 as my DI framework and I am providing a singleton class instance with it.
I also use Quartz Scheduler to schedule jobs. Is there any way to inject the singleton class into the Quartz job?
Dagger 2 module:
#Module
public class MyModule {
#Provides
#Singleton
Messager provideMessager() {
return new CustomMessager();
}
}
Dagger 2 component:
#Component(modules = MyModule.class)
#Singleton
public interface MyComponent {
Messager messager();
}
Quartz Job:
public class MyJob implements Job {
// #Inject
Messager messager;
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
messager.sendMessage("Hello.");
}
}
EDIT
I have created a MyJobScheduler class that calls the Quartz Job:
public class MyJobScheduler {
public void scheduleJob() {
JobDetail myJob = JobBuilder.newJob(MyJob.class)
.withIdentity("myJobId", "Group1")
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("myTriggerId", "Group1")
.startNow()
.build();
Scheduler scheduler = new org.quartz.impl.StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(myJob, trigger);
}
}
EDIT 2
So I managed to configure it to work, but I don't know if this is the correct approach.
First I created a DependencyResolver class, which I use as a singleton:
public class DependencyResolver {
private static DependencyResolver _instance = null;
private static MyComponent _myComponent;
public static MyComponent getMyComponent() {
return _myComponent;
}
protected DependencyResolver() {
// Exists only to defeat instantiation.
}
public static void initialize() {
_myComponent = DaggerMyComponent.builder().build();
}
}
Then I called the initialize method in the main method:
DependencyResolver.initialize();
MyComponent myComponent = DependencyResolver.getMyComponent();
And I used the DependencyResolver in MyJob class to get the Messager singleton instance.
public class MyJob implements Job {
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
MyComponent myComponent = DependencyResolver.getMyComponent();
Messager messager = myComponent.messager();
messager.sendMessage("Hello.");
}
}
Is this the correct way to solve this issue? Any input will be greatly appreciated.
Your EDIT 2 DependencyResolver approach kind of defeats the whole reason to use Dagger to inject the dependencies, because your job gets the dependency from a singleton provider. :-) It completely bypasses the benefit of Dagger, so you might as well just have a singleton on the source dependency itself, like: Messager messager = CustomMessager.getInstance() or something like that.
One reason to use Dependency Injection, is to assist with unit testing, and in this case you're losing the ability to mock your Messager implementation in a unit test.
The proper way to use dependency injection with Quartz jobs is mentioned in the API doc for JobFactory: "This interface may be of use to those wishing to have their application produce Job instances via some special mechanism, such as to give the opertunity for dependency injection."
The trick is to create your own job factory that extends SimpleJobFactory and then you have an opportunity to initialize/inject the job's dependencies, something like this:
public class MyJobFactory extends SimpleJobFactory {
private final MyComponent component;
#Inject
public MyJobFactory(MyComponent component) {
this.component = component;
}
#Override
public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
final Job job = super.newJob(bundle, scheduler);
if (job instanceof MyJob) {
component.inject((MyJob) job);
}
return job;
}
}
And then you tell the scheduler to use your job factory:
scheduler.setJobFactory(myJobFactory);
See the full code here on GitHub