[Logo] Terracotta Discussion Forums
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
[Expert]
Can you help resolve this Quartz JNDI connection issue in Tomcat on Linux?  XML
Forum Index -> Quartz
Author Message
JohnWard

neo

Joined: 07/22/2010 08:54:10
Messages: 2
Offline

I am getting a SQLException when calling the Quartz method StdSchedulerFactory.getScheduler().

The error described below is occurring in a legacy code module that was working for a long time in a WebSphere container. We were hoping not to have to gut this piece of the application. This is the first time we have executed this code in Tomcat on Linux.

Here are the details of the problem (sorry for the necessary obfuscation of names, paths, etc.):

In the following code (from a class called QuartzJobSchedulerFactory), the StdSchedulerFactory.getScheduler() call throws this exception:

org.quartz.SchedulerConfigException: Failure occured during job recovery. [See nested exception: org.quartz.JobPersistenceException: Failed to obtain DB connection from data source 'APPDS': java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/appds' java.sql.SQLException: Connection from pool does not implement javax.sql.XAConnection

Here is the relevant code from QuartzJobSchedulerFactory:

public JobScheduler createJobScheduler()
throws JobSchedulerFactoryException, JobSchedulerException {


Scheduler scheduler = null;
// factory not initialized
if(factory == null){

try {

LogMgr.logError(TransactionTracker.getLogTracer(), this, "???jgw: #1");
LogMgr.logError(TransactionTracker.getLogTracer(), this, "???jgw: Configuring Job Scheduler, config file: " + configFile);
LogMgr.logInfo(TransactionTracker.getLogTracer(), this, "Configuring Job Scheduler, config file: " + configFile);

// get Properties
if (configFile != null) {
LogMgr.logError(TransactionTracker.getLogTracer(), this, "???jgw: constructing via new StdSchedulerFactory(configFile)");
factory = new StdSchedulerFactory(configFile);
} else {
LogMgr.logError(TransactionTracker.getLogTracer(), this, "???jgw: constructing via new StdSchedulerFactory()");
factory = new StdSchedulerFactory();
}

LogMgr.logError(TransactionTracker.getLogTracer(), this, "???jgw: #2");
LogMgr.logInfo(TransactionTracker.getLogTracer(), this, "Retrieving Job Scheduler...");
scheduler = factory.getScheduler();
LogMgr.logError(TransactionTracker.getLogTracer(), this, "???jgw: #3");

} catch (Exception e) {
LogMgr.logError(TransactionTracker.getLogTracer(), this,
"In createJobScheduler(), StdSchedulerFactory.getScheduler() threw the following Exception: " + e.toString());
throw new JobSchedulerFactoryException(e.getMessage(), e);
}

LogMgr.logError(TransactionTracker.getLogTracer(), this, "???jgw: #4");
jobScheduler = new QuartzJobScheduler(scheduler);
//jobScheduler.start();

}

// scheduler not initialized
else if(jobScheduler == null){

try {
LogMgr.logError(TransactionTracker.getLogTracer(), this, "???jgw: #5");
LogMgr.logInfo(TransactionTracker.getLogTracer(), this, "Retrieving Job Scheduler...");
scheduler = factory.getScheduler();
LogMgr.logError(TransactionTracker.getLogTracer(), this, "???jgw: #6");
}
catch (Exception e) {
LogMgr.logError(TransactionTracker.getLogTracer(), this,
"In createJobScheduler(), StdSchedulerFactory.getScheduler() threw the following Exception: " + e.toString());
throw new JobSchedulerFactoryException(e.getMessage(), e);
}
LogMgr.logError(TransactionTracker.getLogTracer(), this, "???jgw: #7");
jobScheduler = new QuartzJobScheduler(scheduler);
//jobScheduler.start();

}

LogMgr.logError(TransactionTracker.getLogTracer(), this, "???jgw: #8");
LogMgr.logInfo(TransactionTracker.getLogTracer(), this, "jobScheduler.isRunning()=" + jobScheduler.isRunning() );
return jobScheduler;
}

One thing worth noting is that the jobScheduler, factory, and configFile variables are static. FindBugs flags the following line:

jobScheduler = new QuartzJobScheduler(scheduler);

with the following details:

Bug: Write to static field <internal-path>.scheduler.QuartzJobSchedulerFactory.jobScheduler from instance method <internal-path>.scheduler.QuartzJobSchedulerFactory.createJobScheduler()
Pattern id: ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD, type: ST, category: STYLE
This instance method writes to a static field. This is tricky to get correct if multiple instances are being manipulated, and generally bad practice.
However, I am reluctant to change this legacy design/implementation because it has worked in all other scenarios and because the author specifically understood that he was writing to these static fields.

Relevant log records (the important Quartz-related error is highlighted in red; the “???jgw:” lines are my debugging, so you can ignore those):

2010-07-20 14:09:45,987 WARN [main] <internal-path>.initialization.ApplicationContextListener- APP:1165618899:Creating Job Scheduler.
2010-07-20 14:09:45,987 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:1165618899:???jgw: #1
2010-07-20 14:09:45,988 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:1165618899:???jgw: Configuring Job Scheduler, config file: quartz.properties
2010-07-20 14:09:45,988 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:1165618899:???jgw: constructing via new StdSchedulerFactory(configFile)
2010-07-20 14:09:46,005 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:1165618899:???jgw: #2
2010-07-20 14:09:46,099 WARN [main] org.quartz.plugins.xml.JobInitializationPlugin- File named 'quartz_jobs.xml' does not exist.
2010-07-20 14:09:46,101 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:1165618899:In createJobScheduler(), StdSchedulerFactory.getScheduler() threw the following Exception: org.quartz.SchedulerConfigException: Failure occured during job recovery. [See nested exception: org.quartz.JobPersistenceException: Failed to obtain DB connection from data source 'APPDS': java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/appds' java.sql.SQLException: Connection from pool does not implement javax.sql.XAConnection [See nested exception: java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/appds' java.sql.SQLException: Connection from pool does not implement javax.sql.XAConnection]]
2010-07-20 14:09:46,101 ERROR [main] <internal-path>.initialization.ApplicationContextListener- APP:1165618899:com.<internal-path>.scheduler.JobSchedulerFactoryException: Failure occured during job recovery.
2010-07-20 14:09:46,101 WARN [main] <internal-path>.initialization.ApplicationContextListener- APP:1165618899:EXITING:com.<internal-path>.initialization.ApplicationContextListener@42d134d0.configureScheduler(ServletContextEvent arg0)
2010-07-20 14:09:46,101 WARN [main] <internal-path>.initialization.ApplicationContextListener- APP:1165618899:EXITING:com.<internal-path>.initialization.ApplicationContextListener@42d134d0.contextInitialized(ServletContextEvent arg0)
2010-07-20 14:11:52,602 ERROR [TP-Processor2] <internal-path>.webinterface.servletfilter.AuthFilter- APP:-1793592338:remoteUser is missing from request. Cannot create user profile. Adding AppError. Request URI: /app/test_login.jsp
2010-07-20 14:11:52,628 ERROR [TP-Processor2] java.lang.Class- APP:-1793592338:AppError added -1793592338
2010-07-20 14:12:26,369 WARN [TP-Processor2] <internal-path>.businessprocess.BusinessActivity- APP:-1793592338:Failed to get role information for workflowId:663140
2010-07-20 14:12:33,903 ERROR [TP-Processor2] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-1793592338:???jgw: #5
2010-07-20 14:12:33,913 WARN [TP-Processor2] org.quartz.plugins.xml.JobInitializationPlugin- File named 'quartz_jobs.xml' does not exist.
2010-07-20 14:12:33,914 ERROR [TP-Processor2] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-1793592338:In createJobScheduler(), StdSchedulerFactory.getScheduler() threw the following Exception: org.quartz.SchedulerConfigException: Failure occured during job recovery. [See nested exception: org.quartz.JobPersistenceException: Failed to obtain DB connection from data source 'APPDS': java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/appds' java.sql.SQLException: Connection from pool does not implement javax.sql.XAConnection [See nested exception: java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/appds' java.sql.SQLException: Connection from pool does not implement javax.sql.XAConnection]]
2010-07-20 14:12:33,914 ERROR [TP-Processor2] java.lang.Class- APP:-1793592338:JobSchedulerFactory.createJobScheduler() threw the following JobSchedulerFactoryException: com.<internal-path>.scheduler.JobSchedulerFactoryException: Failure occured during job recovery.
2010-07-20 14:12:33,914 ERROR [TP-Processor2] <internal-path>.termination.RemovalTaskProcessor- APP:-1793592338:Failed to obtain the jobScheduler from JobSchedulerFactory for transaction ID [termCtx.getTermID()]: 663147 due to the following AccessTerminatorException: com.<internal-path>.termination.AccessTerminatorException: ERROR: JobSchedulerFactoryException
2010-07-20 14:12:33,914 ERROR [TP-Processor2] <internal-path>.termination.RemovalTaskProcessor- APP:-1793592338:Failed to schedule termination task for task: Name = TerminationReminderNotification; TerminationID = 663147. Reason: com.<internal-path>.termination.AccessTerminatorException: ERROR: JobSchedulerFactoryException
2010-07-20 14:12:33,914 ERROR [TP-Processor2] <internal-path>.termination.AccessRemovalProcessor- APP:-1793592338:ProcessRemoval():Failed to process request:663147The root cause is, Failed to create task for termID = 663147.
2010-07-20 14:12:33,915 ERROR [TP-Processor2] <internal-path>.termination.AccessRemovalProcessor- APP:-1793592338:Failed to process removal for resource:FC_XYZ_QA_ITF: The request is:com.<internal-path>.mwinterface.AppRemovalRequest@7bc7956b

By contrast, here is what I get when I run the same code on my Windows PC:

2010-07-20 14:29:03,260 WARN [main] <internal-path>.initialization.ApplicationContextListener- APP:-58259274:Creating Job Scheduler.
2010-07-20 14:29:03,260 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:???jgw: #1
2010-07-20 14:29:03,260 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:???jgw: Configuring Job Scheduler, config file: quartz.properties
2010-07-20 14:29:03,260 INFO [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:Configuring Job Scheduler, config file: quartz.properties
2010-07-20 14:29:03,260 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:???jgw: constructing via new StdSchedulerFactory(configFile)
2010-07-20 14:29:03,323 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:???jgw: #2
2010-07-20 14:29:03,323 INFO [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:Retrieving Job Scheduler...
2010-07-20 14:29:03,432 INFO [main] org.quartz.plugins.management.ShutdownHookPlugin- Registering Quartz shutdown hook.
2010-07-20 14:29:03,432 INFO [main] org.quartz.plugins.xml.JobInitializationPlugin- Registering Quartz Job Initialization Plug-in.
2010-07-20 14:29:03,432 WARN [main] org.quartz.plugins.xml.JobInitializationPlugin- File named 'quartz_jobs.xml' does not exist.
2010-07-20 14:29:03,432 INFO [main] org.quartz.impl.jdbcjobstore.JobStoreTX- Using thread monitor-based data access locking (synchronization).
2010-07-20 14:29:03,526 INFO [main] org.quartz.impl.jdbcjobstore.JobStoreTX- Removed 0 Volatile Trigger(s).
2010-07-20 14:29:03,526 INFO [main] org.quartz.impl.jdbcjobstore.JobStoreTX- Removed 0 Volatile Job(s).
2010-07-20 14:29:03,557 INFO [main] org.quartz.impl.jdbcjobstore.JobStoreTX- Freed 0 triggers from 'acquired' / 'blocked' state.
2010-07-20 14:29:03,573 INFO [main] org.quartz.impl.jdbcjobstore.JobStoreTX- Recovering 0 jobs that were in-progress at the time of the last shut-down.
2010-07-20 14:29:03,573 INFO [main] org.quartz.impl.jdbcjobstore.JobStoreTX- Recovery complete.
2010-07-20 14:29:03,573 INFO [main] org.quartz.impl.jdbcjobstore.JobStoreTX- Removed 0 'complete' triggers.
2010-07-20 14:29:03,573 INFO [main] org.quartz.impl.jdbcjobstore.JobStoreTX- Removed 0 stale fired job entries.
2010-07-20 14:29:03,588 INFO [main] org.quartz.impl.jdbcjobstore.JobStoreTX- JobStoreTX initialized.
2010-07-20 14:29:03,588 INFO [main] org.quartz.impl.StdSchedulerFactory- Quartz scheduler 'AppScheduler' initialized from the specified file : 'quartz.properties' from the class resource path.
2010-07-20 14:29:03,604 INFO [main] org.quartz.impl.StdSchedulerFactory- Quartz scheduler version: 1.4.5
2010-07-20 14:29:03,604 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:???jgw: #3
2010-07-20 14:29:03,604 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:???jgw: #4
2010-07-20 14:29:03,604 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:???jgw: #8
2010-07-20 14:29:03,604 INFO [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:jobScheduler.isRunning()=false
2010-07-20 14:29:03,604 WARN [main] <internal-path>.initialization.ApplicationContextListener- APP:-58259274:Job Scheduler instance loaded.
2010-07-20 14:29:03,635 INFO [main] java.lang.Class- APP:-58259274:ServerHostName=MMKA802778, isPrimaryServer=true
2010-07-20 14:29:03,635 INFO [main] org.quartz.core.QuartzScheduler- Scheduler AppScheduler_$_1 started.
2010-07-20 14:29:03,635 WARN [main] <internal-path>.initialization.ApplicationContextListener- APP:-58259274:Job Scheduler run state = STARTED.
2010-07-20 14:29:03,635 WARN [main] <internal-path>.initialization.ApplicationContextListener- APP:-58259274:EXITING:com.<internal-path>.initialization.ApplicationContextListener@623367.configureScheduler(ServletContextEvent arg0)
2010-07-20 14:29:03,682 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:???jgw: #8
2010-07-20 14:29:03,682 INFO [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:jobScheduler.isRunning()=true
2010-07-20 14:29:03,823 WARN [main] <internal-path>.initialization.ApplicationContextListener- APP:-58259274:Ignore UnexpiredResourceCleanup. Process will not run.
2010-07-20 14:29:03,869 INFO [main] <internal-path>.initialization.ApplicationContextListener- com.<internal-path>.initialization.ApplicationContextListener@623367:Scheduling ActionPendingNotification run.
2010-07-20 14:29:03,869 ERROR [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:???jgw: #8
2010-07-20 14:29:03,869 INFO [main] <internal-path>.scheduler.QuartzJobSchedulerFactory- APP:-58259274:jobScheduler.isRunning()=true

Notice that in this case, I still get the warning about quarts_jobs.xml (so I would think we can rule that out as a cause of the problem)

I am using the following products/versions:

• Quartz 1.4.5
• tc Server 2009-October: 6.0.20.C Maintenance Update General Availability Release
• Apache Tomcat Version: 6.0.20
• tc Server Version: 6.0.20.C
• AMS Version: 2.0.0.SR04
• JDK 1.6.0-18
• OS: Red Hat Enterprise Linux Server release 5.3 (Tikanga)
• Output of “uname -a” command: Linux <internal-server-name> 2.6.18-128.7.1.el5 #1 SMP Wed Aug 19 04:00:49 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux

Here are the contents of my quartz.properties file:

#
# Application: APP (actual name is hidden) - Quartz Scheduling Component
#
# Extending and testing Open Symphony Quartz framework Application Server: IBM
# WebSphere 5.1 Database: Sybase ASE 12
#
# This is a static jobs initializer.
# Additional static jobs need to be configured here.
#
#
#
# Properties file for use by AppSchedulerFactory
# to create a App-Quartz Scheduler Instance.
#
# ===========================================================================
# Main Scheduler Properties ===========++++++++++===========================
# ===========================================================================
#
org.quartz.scheduler.instanceName = AppScheduler
org.quartz.scheduler.instanceId = 1
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false


# ===========================================================================
# ThreadPool ==========================++++++++++===========================
# ===========================================================================
#
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 1
org.quartz.threadPool.threadPriority = 5

# ===========================================================================
# JobStore =================================================================
# ===========================================================================
#
# JDBC:
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = <internal-path>.appquartz.jdbcjobstore.SybaseASEDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = APPDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = false
#org.quartz.jobStore.selectWithLockSQL =


# ===========================================================================
# Datasources ==============================================================
# ===========================================================================
#
# JDBC direct
#org.quartz.dataSource.APPDS.driver=com.sybase.jdbc2.jdbc.SybDriver
#org.quartz.dataSource.APPDS.URL=
#org.quartz.dataSource.APPDS.user=[hidden]
#org.quartz.dataSource.APPDS.password=[hidden]
#org.quartz.dataSource.APPDS.maxConnections=5

# JDBC via JNDI
org.quartz.dataSource.APPDS.jndiURL=java:comp/env/jdbc/appds



# ===========================================================================
# Scheduler Plugins ========================================================
# ===========================================================================
#

org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingTriggerHistoryPlugin
org.quartz.plugin.triggHistory.triggerFiredMessage = Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss MM/dd/yyyy}
org.quartz.plugin.triggHistory.triggerCompleteMessage = Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy} with resulting trigger instruction code: {9}

org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin
#org.quartz.plugin.jobInitializer.fileName = jobs.xml
org.quartz.plugin.jobInitializer.overWriteExistingJobs = false
org.quartz.plugin.jobInitializer.failOnFileNotFound = false

org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownhook.cleanShutdown = true

# ===========================================================================
# Listeners =========================================================
# ===========================================================================
#

org.quartz.triggerListener.AppTriggerListener.class = <internal-path>.appquartz.job.AppTriggerListener

Here are the contents of my app.xml file (less irrelevant tags):

<Context>

<Resource name="jdbc/appds"
type="javax.sql.DataSource" auth="Container"
driverClassName="com.sybase.jdbc2.jdbc.SybDriver"
url="jdbc:sybase:Tds:<internal-server-name>:1029/app"
MaxConnection="10" MinConnection="1"
username="[hidden]" password="[hidden]" />

</Context>

I have also tried unsuccessfully with this effective variant of app.xml:

<Context>

<Resource
name="jdbc/appds"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
type="javax.sql.DataSource"
auth="Container"
driverClassName="com.sybase.jdbc2.jdbc.SybDriver"
url="jdbc:sybase:Tds:<internal-server-name>:1029/app"
MaxConnection="10" MinConnection="1"
username="[hidden]" password="[hidden]" />

</Context>

Please let me know what you recommend. I have already tried Quartz 1.6.6 and still got the same exception. Should I try the latest version of Quartz? Should I try something else that I haven’t yet tried? Is the use of the static variables causing a problem?

Thanks for any help,
John
JohnWard

neo

Joined: 07/22/2010 08:54:10
Messages: 2
Offline

It appears that we have been able to work around this problem by using the following configuration in quartz.properties:

# JDBC direct
org.quartz.dataSource.APPDS.driver=com.sybase.jdbc2.jdbc.SybDriver
org.quartz.dataSource.APPDS.URL=jdbc:sybase:Tds:<internal-server-name>:1029/appdbname
org.quartz.dataSource.APPDS.user=[hidden]
org.quartz.dataSource.APPDS.password=[hidden]
org.quartz.dataSource.APPDS.maxConnections=30

# JDBC via JNDI
#org.quartz.dataSource.APPDS.jndiURL=java:comp/env/jdbc/appds

So, we have effectively switched from using the JNDI method to using the direct JDBC method.

We are fine for now, but I will still keep this thread open until the root cause can be identified.

- John
jhouse

seraphim
[Avatar]
Joined: 11/06/2009 15:29:56
Messages: 1703
Offline


It's hard to tell for sure what's going on, with all of your wrapper classes etc. showing up in the stack traces.


However, this:

Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/appds' java.sql.SQLException: Connection from pool does not implement javax.sql.XAConnection
 


Indicates that something in quartz is configured to use JTA (XA) transactions and is not finding the datasource to contain XAConnections.

However looking at your quartz.properties file's contents, I can't figure out what/why that would be.
Badri

neo

Joined: 04/01/2013 05:57:32
Messages: 3
Offline

I am getting the below error. Kindly let me know where would be the issue.



INFO: QuartzInitializer: Quartz Scheduler failed to initialize: org.quartz.SchedulerConfigException: Failure occured during job recovery. [See nested exception: org.quartz.JobPersistenceException: Failed to obtain DB connection from data source 'test': java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:jdbc/test' javax.naming.NameNotFoundException: Name [jdbc/test] is not bound in this Context. Unable to find [jdbc]. [See nested exception: java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:jdbc/test' javax.naming.NameNotFoundException: Name [jdbc/test] is not bound in this Context. Unable to find [jdbc].]]
Apr 3, 2013 12:25:35 PM org.apache.catalina.core.StandardContext loadOnStartup
SEVERE: Servlet /SampleWeb threw load() exception
java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:jdbc/test' javax.naming.NameNotFoundException: Name [jdbc/test] is not bound in this Context. Unable to find [jdbc].
at org.quartz.utils.JNDIConnectionProvider.getConnection(JNDIConnectionProvider.java:163)
 
Forum Index -> Quartz
Go to:   
Powered by JForum 2.1.7 © JForum Team