JNDI issue with Websphere 6 UserTrasaction and Quartz Scheduler - java

I have my Web Application running on WebSphere 6.0 and also there are some Quartz Scheduler Tasks. If I do the lookup like that in hibernate.cfg.xml:
<property name="jta.UserTransaction">java:comp/UserTransaction</property>
It works fine with my Web Application, but any threads initiated by Quartz Timers fail to access the DB using that lookup string. But if I use
<property name="jta.UserTransaction">jta/usertransaction</property>
Then it is the opposite. I will get quartz timers working but I can't do the lookup inside my Web Application.
Is there any way to make them both work with same hibernate configuration?
EDT: here is my quartz.properties file. By the way Quartz Version is 1.5.2.
org.quartz.scheduler.instanceName = TestScheduler
org.quartz.scheduler.instanceId = one
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 4
org.quartz.jobStore.misfireThreshold = 5000
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

I don't know if this is relevant to you but I recently had a similar problem. My issue was remote and local access and altering my design a bit and adding the interface names to my #Local & #Remote annotations worked for me.

I think you miss the transaction management in your quartz.properties.
Something like this:
org.quartz.scheduler.userTransactionURL=jta/usertransaction
org.quartz.scheduler.wrapJobExecutionInUserTransaction=true
The idea is to tell Quartz to wrap the job execution in a transaction and where to get it.

Related

Spring Boot : Disable Quartz Scheduler

We are using Quartz Scheduler in our Spring Boot Application.
There is a scenario for which we want to disable it.
We have tried using #ConditionalOnProperty(name = Constant.QUARTZ_ENABLED) option on our class.
We have defined quartz.enabled = false property in application.properties file.
However when we run on Tomcat server locally on Spring Tool Suite it is working as expected (meaning it is not invoking the quartz scheduler).
But when same code is deployed on Weblogic, the scheduler is still running.
Should we try putting #ConditionalOnProperty(name = Constant.QUARTZ_ENABLED) annotation at method level. specifically the method where trigger is used?
We have gone through the options mentioned on various forums but still not reached the solution.
Is there any way we can
1. Stop the scheduler from starting
Or
2. Stop the Job from getting triggered
Thanks in advance.

Quartz + Spring : Configure jobs to run on specific time using JobStore

I'm trying out Quartz scheduler and managed to get it to work with Spring using Maven.
What I need to do is configure Quartz to store the jobs so that for a scheduled time it may execute the job. As far as I know there are two types of triggers in Quartz, Simple and Cron. And I also found out that there is something called JobStore in Quartz. I got it configured to some extent.
Could someone please give me a good reference/references on how to setup Quartz, JobStore? Big help, thank you.
You can have a look at these links
Quartz JobStore with Spring Framework
http://trimplement.com/using-spring-and-quartz-with-jobstore-properties/
If you still cant figure it out then let me know
Just to give you another option, have you try task scheduling of Spring?. Nowadays I change all my old Quartz jobs for this and is easier to configure and you can use the annotations.
http://spring.io/blog/2010/01/05/task-scheduling-simplifications-in-spring-3-0/
You will usually create a Scheduler from a factory class. Quartz can be setup in several ways.
By using the org.quartz.impl.StdSchedulerFactory.getDefaultScheduler(). This will load the quartz.properties file in the Quartz distribution if you have not provided your own.
By specifying your configuration as Key-Value pairs in a quartz.properties file and loading it in org.quartz.impl.StdSchedulerFactory(java.lang.String fileName).getScheduler().
By specifying your configuration in a java.util.Properties as Key-Value pairs and loading it in org.quartz.impl.StdSchedulerFactory(java.util.Properties props).getScheduler().
By using the spring-context-support jar from the Spring Framework and using a higher level abstraction such as org.springframework.scheduling.quartz.SchedulerFactoryBean.
etc.
Quartz will start triggering jobs only when the org.quartz.Scheduler#start() has been invoked. Until this method is called the Scheduler will be in Standby mode.
The Scheduler can be destroyed to release threads by calling org.quartz.Scheduler#shutdown().
Example of Bootstrapping Quartz with Spring
#org.springframework.context.annotation.Configuration
public class QuartzExample {
...
#org.springframework.context.annotation.Bean
public org.springframework.scheduling.quartz.SchedulerFactoryBean schedulerFactory() {
org.springframework.scheduling.quartz.SchedulerFactoryBean factoryBean = new org.springframework.scheduling.quartz.SchedulerFactoryBean();
return factoryBean;
}
}
The bean definition above is enough to perform the following configuration:-
JobFactory - The default is Spring’s org.springframework.scheduling.quartz.AdaptableJobFactory, which supports java.lang.Runnable objects as well as standard Quartz org.quartz.Job instances.
ThreadPool - Default is a Quartz org.quartz.simpl.SimpleThreadPool with a pool size of 10. This is configured through the corresponding Quartz properties.
SchedulerFactory - The default used here is the org.quartz.impl.StdSchedulerFactory, reading in the standard quartz.properties from quartz.jar.
JobStore - The default used is org.quartz.simpl.RAMJobStore which does not support persistence and is not clustered.
Life-Cycle - The org.springframework.scheduling.quartz.SchedulerFactoryBean implements org.springframework.context.SmartLifecycle and org.springframework.beans.factory.DisposableBean which means the life-cycle of the scheduler is managed by the Spring container. The org.quartz.Scheduler#start() is called in the start() implementation of SmartLifecycle after initialization and the org.quartz.Scheduler#shutdown() is called in the destroy() implementation of DisposableBean at application teardown.
You can override the startup behaviour by setting org.springframework.scheduling.quartz.SchedulerFactoryBean().setAutoStartup(false). With this setting you have to manually start the scheduler.
All these default settings can be overridden by the calling the various setter methods on org.springframework.scheduling.quartz.SchedulerFactoryBean.
I have provided a full working example on Github. If you are interested in an example that saves the jobs in a database checkout the HSQLDB branch of the same repository.

Clustered Quartz trigger is paused by Camel on shutdown

I have following configuration in a quartz.properties
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.instanceName=JobCluster
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.dataSource=myDataSource
org.quartz.dataSource.chargebackDataSource.jndiURL=jdbc/myDataSource
org.quartz.jobStore.isClustered=true
org.quartz.threadPool.threadCount=5
Spring configuration looks like this:
<bean id="quartz2" class="org.apache.camel.component.quartz2.QuartzComponent">
<property name="propertiesFile" value="quartz.properties"/>
</bean>
<route>
<from uri="quartz2://myTrigger?job.name=myJob&job.durability=true&stateful=true&trigger.repeatInterval=60000&trigger.repeatCount=-1"/>
<to uri="bean:myBean?method=retrieve"/>
....
On application shut down the Quartz trigger state changed to PAUSED and after the next start never changed to WAITING again so never fired again.
Is it possible to configure quartz/camel somehow to resume trigger after the application restart?
Camel version is 2.12.0.
Spring version 3.2.4.RELEASE
Actually such behavior contradicts with theit statement at guideline:
If you use Quartz in clustered mode, e.g. the JobStore is clustered. Then the Quartz2 component will not pause/remove triggers when a node is being stopped/shutdown. This allows the trigger to keep running on the other nodes in the cluster.
If you want to dynamic suspend/resume routes as the
org.apache.camel.impl.ThrottlingRoutePolicy
does then its advised to use org.apache.camel.SuspendableService as it allows for fine grained suspend and resume operations. And use the org.apache.camel.util.ServiceHelper to aid when invoking these operations as it support fallback for regular org.apache.camel.Service instances.
For more details please refer RoutePolicy and Quartz Component
Hope this migh help

Quartz persistent job scheduler implementation in java using oracle read only access

Here is scenario,
I am working on one web application,where I am using java, spring, oracle. My requirement is schedule some job where user should specify execution time by some UI and job should be persistent once schedule even if server restarted or application redeployed.
From last few days I am going through lots of stackoverflow post regarding quartz persistence scheduler, but here is tricky part I can not execute any update or insert statement from my java code, I am only allowed to do all db stuff in plsql procedure and call that procedure from java code.
So, the problem is I can't go for quartz persistence implementation directly.It will very great full if anyone tell me right approach to deal with it.
in short how I can implement my own table structure and plsql procedure to make job persistence,which I can load once on application/server start and also allow user to update trigger time and other parameters.
Thanks
What you are looking is for the Quartz JdbcJobStore which stores the jobs and track their execution. Please read the following:
For configuring the JdbcJobStore read this (TX) or this (CMT)
For configuring the data sources read this
#Gan, If you want, you can customize quartz persistance by overriding JobStoreCMT class of Quartz and using that as your job store class in quartz.properties as value for property org.quartz.jobStore.class.
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = <package>.CustomJobStoreCMT

Spring Framework Connecting JVM with each other

I have 4 servers and JVM is installed on them. I wrote a java service that Quartz calls this services every 10 minutes. But in 4 servers, every 10 minutes 4 calls are done. This sitiuation creates race condition. I want only one service on 4 JVM.
How can I do that with Spring Framework?
This is actually pretty easy to set up with Quartz. Spring itself cannot help you much here since it is unaware of the other JVMs that are running. Quartz on the other hand has the concept of a clustered scheduler.
Basically you need to set up a single database that all the 4 JVMs can share. This will be used as a scheduler for all 4 instances. When a job is scheduled, it is run by only one of the instances using the clustered scheduler.
Taken from the Quartz website wiki for clustering (
http://www.opensymphony.com/quartz/wikidocs/ConfigJDBCJobStoreClustering.html), this is an example configuration on how to set up the clustered scheduler. You can also set these properties directly from spring if you are configuring your scheduler that way.
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:#polarbear:1521:dev
org.quartz.dataSource.myDS.user = quartz
org.quartz.dataSource.myDS.password = quartz
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 0 from dual
Your question isn't very clear, so let me see if I'm understanding you: you have 4 servers, each running Quartz inside a VM, and each server has the same quartz job scheduled to run every 10 minutes, using a cron expression. Every 10 minutes, all 4 servers kick off the same job, creating your race condition as they all try to do the same thing at the same time.
This isn't really a job for Spring. However, Quartz does have clustering ability, where you configure a job to run only a single server in the cluster. It uses a shared database to coordinate which servers run which job, and makes sure they don't all do it together.
The docs have some info on this here, but in the usual opensymphony.com style they're pretty sparse and unhelpful.
What I do in our web application is for each job to be wrapped in a class that takes out a global lock across your cluster (I use memcached, as I don't really care if the task gets run too often), and only runs the task if it got the lock. It can then release the lock when the task completes (don't forget to do this in a finally).
One advantage of wrapping each job rather than changing the scheduler is that you can have some jobs that run on all the machines, and some that only run on one.

Categories