[Logo] Terracotta Discussion Forums
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
[Expert]
Quartz 2.1 on Websphere 7  XML
Forum Index -> Quartz
Author Message
fuero

neo

Joined: 10/09/2011 15:39:26
Messages: 2
Offline

Hi,

Quartz 2.1 jobs are unable to lookup resources via JNDI. It seems that the application's context is not passed on to the thread launched by Quartz.
As far as I can see, everything concerning Quartz is fine,

But when trying to lookup a datasource like this:
Code:
InitialContext inictx = new InitialContext();
 Context ctx = (Context) inictx.lookup("java:comp/env");
 Object o = ctx.lookup("jdbc/datasource");

Websphere replies with the dreaded NMSV0310E.

A simple Testservlet using the commonj API directly launching sample Work can successfully perform the above lookup.

quartz.properties
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 1
org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer = true
org.quartz.scheduler.skipUpdateCheck = true

org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

org.quartz.threadExecutor.class=org.quartz.commonj.WorkManagerThreadExecutor
org.quartz.threadExecutor.workManagerName=java:comp/env/wm/default

org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames = C:/path/to/quartz-jobs.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
org.quartz.plugin.jobInitializer.scanInterval = 10
org.quartz.plugin.jobInitializer.wrapInUserTransaction = false 


Excerpt from the logfile, edited to remove actual file locations and company names:
2011-10-09 23:02:22 WorkmanagerServlet INFO - Servlet init
2011-10-09 23:02:23 StdSchedulerFactory INFO - Using custom implementation for ThreadExecutor: org.quartz.commonj.WorkManagerThreadExecutor
2011-10-09 23:02:23 SimpleThreadPool INFO - Job execution threads will use class loader of thread: WebContainer : 0
2011-10-09 23:02:23 QuartzSchedulerThread INFO - QuartzSchedulerThread Inheriting ContextClassLoader of thread: WebContainer : 0
2011-10-09 23:02:23 SchedulerSignalerImpl INFO - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2011-10-09 23:02:23 QuartzScheduler INFO - Quartz Scheduler v.2.1.0 created.
2011-10-09 23:02:23 XMLSchedulingDataProcessorPlugin INFO - Registering Quartz Job Initialization Plug-in.
2011-10-09 23:02:23 RAMJobStore INFO - RAMJobStore initialized.
2011-10-09 23:02:23 QuartzScheduler INFO - Scheduler meta-data: Quartz Scheduler (v2.1.0) 'QuartzScheduler' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 1 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

2011-10-09 23:02:23 StdSchedulerFactory INFO - Quartz scheduler 'QuartzScheduler' initialized from the specified file : 'C:/path/to/quartz.properties'
2011-10-09 23:02:23 StdSchedulerFactory INFO - Quartz scheduler version: 2.1.0
2011-10-09 23:02:23 XMLSchedulingDataProcessorPlugin DEBUG - Scheduled file scan job for data file: C:/path/to/quartz-jobs.xml, at interval: 10000
2011-10-09 23:02:23 XMLSchedulingDataProcessor DEBUG - Utilizing schema packaged in local quartz distribution jar.
2011-10-09 23:02:23 XMLSchedulingDataProcessor INFO - Parsing XML file
2011-10-09 23:02:23 XMLSchedulingDataProcessor DEBUG - Found 0 delete job group commands.
2011-10-09 23:02:23 XMLSchedulingDataProcessor DEBUG - Found 0 delete trigger group commands.
2011-10-09 23:02:23 XMLSchedulingDataProcessor DEBUG - Found 0 delete job commands.
2011-10-09 23:02:23 XMLSchedulingDataProcessor DEBUG - Found 0 delete trigger commands.
2011-10-09 23:02:23 XMLSchedulingDataProcessor DEBUG - Directive 'overwrite-existing-data' not specified, defaulting to true
2011-10-09 23:02:23 XMLSchedulingDataProcessor DEBUG - Directive 'ignore-duplicates' not specified, defaulting to false
2011-10-09 23:02:23 XMLSchedulingDataProcessor DEBUG - Found 1 job definitions.
2011-10-09 23:02:23 XMLSchedulingDataProcessor DEBUG - Parsed job definition: JobDetail 'Jobs.IMN008': jobClass: 'foo.bar.quartz.wrappers.IMN008Job concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
2011-10-09 23:02:23 XMLSchedulingDataProcessor DEBUG - Found 1 trigger definitions.
2011-10-09 23:02:23 XMLSchedulingDataProcessor DEBUG - Parsed trigger definition: Trigger 'TRIGGER_GROUP.mytrigger': triggerClass: 'org.quartz.impl.triggers.CronTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: null
2011-10-09 23:02:23 XMLSchedulingDataProcessor INFO - Adding 1 jobs, 1 triggers.
2011-10-09 23:02:23 XMLSchedulingDataProcessor INFO - Adding job: Jobs.IMN008
2011-10-09 23:02:23 XMLSchedulingDataProcessor DEBUG - Scheduling job: Jobs.IMN008 with trigger: TRIGGER_GROUP.mytrigger
2011-10-09 23:02:23 QuartzScheduler INFO - Scheduler QuartzScheduler_$_NON_CLUSTERED started.
2011-10-09 23:02:23 QuartzSchedulerThread DEBUG - batch acquisition of 1 triggers
2011-10-09 23:02:23 PropertySettingJobFactory DEBUG - Producing instance of Job 'JobSchedulingDataLoaderPlugin.JobSchedulingDataLoaderPlugin_jobInitializer_quartz-jobs_xml', class=org.quartz.jobs.FileScanJob
2011-10-09 23:02:23 PropertySettingJobFactory WARN - No setter on Job class org.quartz.jobs.FileScanJob for property 'JobSchedulingDataLoaderPlugin_jobInitializer'
2011-10-09 23:02:23 PropertySettingJobFactory WARN - No setter on Job class org.quartz.jobs.FileScanJob for property 'FILE_SCAN_LISTENER_NAME'
2011-10-09 23:02:23 PropertySettingJobFactory WARN - No setter on Job class org.quartz.jobs.FileScanJob for property 'FILE_NAME'
2011-10-09 23:02:23 JobRunShell DEBUG - Calling execute on job JobSchedulingDataLoaderPlugin.JobSchedulingDataLoaderPlugin_jobInitializer_quartz-jobs_xml
2011-10-09 23:02:23 QuartzSchedulerThread DEBUG - batch acquisition of 1 triggers
2011-10-09 23:02:33 PropertySettingJobFactory DEBUG - Producing instance of Job 'JobSchedulingDataLoaderPlugin.JobSchedulingDataLoaderPlugin_jobInitializer_quartz-jobs_xml', class=org.quartz.jobs.FileScanJob
2011-10-09 23:02:33 PropertySettingJobFactory WARN - No setter on Job class org.quartz.jobs.FileScanJob for property 'JobSchedulingDataLoaderPlugin_jobInitializer'
2011-10-09 23:02:33 PropertySettingJobFactory WARN - No setter on Job class org.quartz.jobs.FileScanJob for property 'FILE_SCAN_LISTENER_NAME'
2011-10-09 23:02:33 PropertySettingJobFactory WARN - No setter on Job class org.quartz.jobs.FileScanJob for property 'LAST_MODIFIED_TIME'
2011-10-09 23:02:33 PropertySettingJobFactory WARN - No setter on Job class org.quartz.jobs.FileScanJob for property 'FILE_NAME'
2011-10-09 23:02:33 JobRunShell DEBUG - Calling execute on job JobSchedulingDataLoaderPlugin.JobSchedulingDataLoaderPlugin_jobInitializer_quartz-jobs_xml
2011-10-09 23:02:33 QuartzSchedulerThread DEBUG - batch acquisition of 1 triggers
2011-10-09 23:02:43 PropertySettingJobFactory DEBUG - Producing instance of Job 'JobSchedulingDataLoaderPlugin.JobSchedulingDataLoaderPlugin_jobInitializer_quartz-jobs_xml', class=org.quartz.jobs.FileScanJob
2011-10-09 23:02:43 JobRunShell DEBUG - Calling execute on job JobSchedulingDataLoaderPlugin.JobSchedulingDataLoaderPlugin_jobInitializer_quartz-jobs_xml
2011-10-09 23:02:43 QuartzSchedulerThread DEBUG - batch acquisition of 1 triggers
2011-10-09 23:02:53 PropertySettingJobFactory DEBUG - Producing instance of Job 'JobSchedulingDataLoaderPlugin.JobSchedulingDataLoaderPlugin_jobInitializer_quartz-jobs_xml', class=org.quartz.jobs.FileScanJob
2011-10-09 23:02:53 JobRunShell DEBUG - Calling execute on job JobSchedulingDataLoaderPlugin.JobSchedulingDataLoaderPlugin_jobInitializer_quartz-jobs_xml
2011-10-09 23:02:53 QuartzSchedulerThread DEBUG - batch acquisition of 1 triggers
2011-10-09 23:03:00 PropertySettingJobFactory DEBUG - Producing instance of Job 'Jobs.IMN008', class=foo.bar.quartz.wrappers.IMN008Job
2011-10-09 23:03:00 JobRunShell DEBUG - Calling execute on job Jobs.IMN008
2011-10-09 23:03:00 IMN008Job TRACE - local:
2011-10-09 23:03:00 IMN008Job TRACE - java:
2011-10-09 23:03:00 IMN008Job INFO - com.ibm.ws.naming.java.javaURLContextImpl comp
2011-10-09 23:03:00 IMN008Job INFO - javax.ejb.spi.HandleDelegate HandleDelegate
2011-10-09 23:03:00 IMN008Job INFO - org.omg.CORBA.ORB ORB
2011-10-09 23:03:00 IMN008Job INFO - com.ibm.ws.naming.java.javaURLContextImpl env
2011-10-09 23:03:00 IMN008Job TRACE - java:comp/env 


Version / OS Info:
Quartz 2.1.0
Websphere 7.0.0.17 Standalone Application Server, No Cluster
Windows 2008 R2 SP1
light5

ophanim
[Avatar]
Joined: 01/14/2011 20:32:56
Messages: 554
Offline

Hello fuero,

I am not familiar with Websphere, but from your logoutput, it seems like Quartz is functioning just fine to me. Where is the error and stacktrace?

If you are saying you failed to look up datasource, where is this lookup code running? Inside your Job impl? Have you ensure this datasource lookup work as standalone without running in quartz?

Zemian Deng
---------------
Looking for a web UI to manage Quartz?
Try http://code.google.com/p/myschedule
[WWW]
fuero

neo

Joined: 10/09/2011 15:39:26
Messages: 2
Offline

@light5:
Yes, lookups are done inside a job implementation.
As stated, it works without Quartz using commonj API.
As to the error, the code I ran just enumerated the contexts, so no lookup error there. But the error websphere throws if one tries to lookup a nonexistent resource is the one I mentioned.

Anyhow, I found and fixed the problem:

Quartz's internal threads are started by the thread executor mentioned by the Websphere-specific JIRA tickets, but the thread pool implementation still runs threads via Thread.start().

Somebody please post this on JIRA, my credentials don't work.

quartz-2.1.0-websphere-threadpool-fix.patch:
Thread executor is now passed to the thread pool, and it uses it to run worker threads.

quartz-2.1.0-filescanjob-warnings-fix.patch:
Fixes the warnings PropertySettingJobFactory generates.
 Filename quartz-2.1.0-filescanjob-warnings-fix.patch [Disk] Download
 Description Fixes the warnings PropertySettingJobFactory generates.
 Filesize 5 Kbytes
 Downloaded:  206 time(s)

 Filename quartz-2.1.0-websphere-threadpool-fix.patch [Disk] Download
 Description Fixes for WAS, apply against Quartz 2.1.0
 Filesize 6 Kbytes
 Downloaded:  327 time(s)

kwong

neo

Joined: 10/11/2011 03:15:07
Messages: 7
Offline

Instead of coupling ThreadPool and ThreadExecutor, how about making a WorkManagerThreadPool? And let SimpleThreadPool, ZeroThreadPool and even ThreadPool as they are. Maybe this is the time in v2.2 to revisit the role of ThreadPool and ThreadExecutor as a whole.
jhouse

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


Over the years the whole codebase has become a series of work-arounds for Websphere and DB2.

Wish they would play nice like every other app server and database.
kwong

neo

Joined: 10/11/2011 03:15:07
Messages: 7
Offline

You really did a good job on that. I worked with Quartz since v1.5. At that time, I did lots of hacks on Quartz to make it worked with WebSphere. I am happy to see there is natural way to cope with it.
FabianM

neo

Joined: 12/15/2011 08:45:52
Messages: 1
Offline

Hi,

I'm sorry to spoil the party but the submitted patch doesn't really work as the thread that you submit to the executor is only visible as a Runnable, you loose any control over it, any join/interrupt or anything you call will be useless. The WAS executor never calls Thread.start but only Thread.run.

By the way it looks SimpleThreadPool is very simple and a bit outdated given the join/wait synchronization. I think you need a org.quartz.spi.ThreadPool implementation that delegates everything to the WorkManager which should be simple to implement.

Here is a test that shows how to control a runnable externaly. Interrupt does absolutely nothing for the first test.
Code:
 	public static BlockingQueue<String> testMyQueue = new ArrayBlockingQueue<String>(5);
 	
 	public static class TestThread extends Thread{
 		@Override
 		public void run() {
 			try {
 				System.out.println("WAITING" +testMyQueue.size());
 				TimeUnit.SECONDS.sleep(5);
 			} catch (InterruptedException e) {
 				testMyQueue.offer("Hit me!!");
 				System.out.println("Interrupted "+testMyQueue.size() );
 				e.printStackTrace();
 			}
 		}
 	}
 	
 	@Test
 	public void notTheRightThread() throws InterruptedException{
 		Executor exec = Executors.newFixedThreadPool(15);
 		TestThread test = new TestThread();
 		exec.execute(test);
 		/*Should interrupt*/
 		TimeUnit.SECONDS.sleep(1);
 		test.interrupt();
 		String oneUp = testMyQueue.poll(5,TimeUnit.SECONDS);
 		Assert.assertNotNull(oneUp);
 	}
 	
 	@Test
 	public void theRightThread() throws InterruptedException{
 		Executor exec = Executors.newFixedThreadPool(15);
 		TestThread test = new TestThread();
 		FutureTask<Void> testTask = new FutureTask<Void>(test, null);
 		exec.execute(testTask);
 		TimeUnit.SECONDS.sleep(1);
 		/*Should interrupt*/
 		testTask.cancel(true);
 		String oneUp = testMyQueue.poll(5,TimeUnit.SECONDS);
 		Assert.assertNotNull(oneUp);
 	}	
 


 
Forum Index -> Quartz
Go to:   
Powered by JForum 2.1.7 © JForum Team