|
From: Colin S. <col...@ex...> - 2004-02-19 21:00:42
|
Hey Juergen,
The Quartz stuff looks like good stuff on an initial lookover.
I do have a comment about your refactoring of MethodInvokingFactoryBean.
For the static method call case, your refactoring is arguably cleaner=20
because the same property is used for specifyng the method name as for=20
the non-static case, but on the other hand, static methods are probably=20
one of the most common uses of this class, and you've turned a one=20
property config into a two property config, i.e.
<bean id=3D"qa-util-initProfileImpl"=20
class=3D"org.springframework.beans.factory.config.MethodInvokingFactoryBe=
an">
<property=20
name=3D"staticMethod"><value>com.whatever.qaserver.device.ProfileClassesI=
nit.initProfileClasses</value></property>
</bean>
tnow becomes
<bean id=3D"qa-util-initProfileImpl"=20
class=3D"org.springframework.beans.factory.config.MethodInvokingFactoryBe=
an">
<property=20
name=3D"targetMethod"><value>initProfileClasses</value></property>
<property=20
name=3D"targetClass"><value>com.whatever.qaserver.device.ProfileClassesIn=
it</value></property>
</bean>
As well, this also breaks backwards compatibility for anybody using it.=20
Perhaps you can add back the
staticMethod
property, and on a set, the code inside it would break up the supplied=20
string into calls to setTargetMethod and setTargetClass (it would have=20
to create the class itself).
This would allow both forms to be used, and keep backwards compatibility.=
..
Regards,
Colin
j=FCrgen h=F6ller [werk3AT] wrote:
>The Quartz support is already in CVS, and also in use within the werk3AT=
app it was intended for... feel free to check it out!
>=20
>Juergen
>=20
>
>________________________________
>
>Von: spr...@li... im Auftrag vo=
n j=FCrgen h=F6ller [werk3AT]
>Gesendet: Do 19.02.2004 16:54
>An: spr...@li...
>Betreff: RE: [Springframework-developer] Quartz support
>
>
>
>Daniel,
>
>As you say, this is most likely caused by the fact that Quartz uses its =
own threads. WebSphere seems to associate the JNDI context information wi=
th container-managed threads; unfortunately, this does not apply to Quart=
z threads.
>
>However, there's a strategy that should work: pre-locate the JNDI object=
s, and pass the objects to Quartz' job data map. This way, the Quartz job=
should receive the pre-located objects when running in its own thread, n=
ot needing to do a JNDI lookup itself.
>
>The Quartz support classes (to be committed within an hour!) provide the=
following:
>
>- a SchedulerFactoryBean that sets up a Quartz Scheduler, allowing to re=
gister JobDetails, Calendars and Triggers with it
>
>- convenience subclasses of JobDetail, CronTrigger and SimpleTrigger tha=
t allow for easy bean-style usage; the latter allow for implicit registra=
tion of an associated JobDetail
>
>- a FactoryBean for a JobDetail that invokes a method of an existing obj=
ect, to avoid the need for writing one-line Job implementations that just=
delegate to a business method
>
>- a convenience implementation of Quartz' Job interface, applying job da=
ta map entries as bean properties
>
>A configuration example:
>
> <bean id=3D"scheduler" class=3D"org.springframework.scheduling.q=
uartz.SchedulerFactoryBean">
> <property name=3D"triggers">
> <list>
> <ref bean=3D"myTrigger1"/>
> <ref bean=3D"myTrigger2"/>
> </list>
> </property>
> </bean>
>
> <bean id=3D"myJobDetail1" class=3D"org.springframework.schedulin=
g.quartz.JobDetailBean">
> <property name=3D"jobClass"><value>werk3.example.MyJob</=
value></property>
> <property name=3D"jobDataAsMap">
> <map>
> <entry key=3D"testBean">
> <bean class=3D"org.springframewo=
rk.beans.TestBean">
> <property name=3D"age"><=
value>99</value></property>
> </bean>
> </entry>
> </map>
> </property>
> </bean>
>
> <bean id=3D"myJobDetail2" class=3D"org.springframework.schedulin=
g.quartz.MethodInvokingJobDetailFactoryBean">
> <property name=3D"targetObject"><ref bean=3D"exampleServ=
ice"/></property>
> <property name=3D"targetMethod"><value>doSomething</valu=
e></property>
> </bean>
>
> <bean id=3D"myTrigger1" class=3D"org.springframework.scheduling.=
quartz.CronTriggerBean">
> <property name=3D"jobDetail"><ref bean=3D"myJobDetail1"/=
></property>
> <property name=3D"cronExpression"><value>0/5 * * * * ?</=
value></property>
> </bean>
>
> <bean id=3D"myTrigger2" class=3D"org.springframework.scheduling.=
quartz.SimpleTriggerBean">
> <property name=3D"jobDetail"><ref bean=3D"myJobDetail2"/=
></property>
> <property name=3D"repeatInterval"><value>1000</value></p=
roperty>
> </bean>
>
>MyJob (as referenced from "myJobDetail1") can be implemented as follows:
>
> public static class MyJob extends QuartzJobBean {
>
> private TestBean testBean;
>
> public void setTestBean(TestBean testBean) {
> this.testBean =3D testBean;
> }
>
> protected void executeInternal(JobExecutionContext jobEx=
ecutionContext) {
> System.out.println("Executing job..." + testBean=
.getAge());
> }
> }
>
>Note that the "testBean" entry in the job data map is automatically appl=
ied as bean property in MyJob.
>
>As a side note, I've refactored Colin's MethodInvokingFactoryBean into o=
rg.springframework.util.MethodInvoker, with MethodInvokingFactoryBean and=
MethodInvokingJobDetailFactoryBean as subclasses. They provide exactly t=
he same invocation capabilities.
>
>Juergen
>
>
>-----Original Message-----
>From: spr...@li...
>[mailto:spr...@li...]On Behalf
>Of Daniel Potter
>Sent: Thursday, February 19, 2004 4:17 PM
>To: spr...@li...
>Subject: Re: [Springframework-developer] Quartz support
>
>
>Juergen,
>I have a question regarding these classes and/or your general experience
>using Quartz with Spring in an J2EE container. We've run into JNDI
>lookup issues with jobs that attempt to use Spring beans that contain
>references to JNDI resources (thru a JndiObjectFactoryBean). It appears
>the Quartz job doesn't know it's running within the container (even
>though the scheduler is started in the init() method of a servlet), so i=
t's
>dependencies fail to locate the default JNDI context (and therefore fail
>to locate their JNDI dependencies). I assume this is because the
>scheduler is running in its own thread, so it doesn't have any implicit
>knowledge of the container. To get around this, we've been
>forced to use a separate Spring config file for the Quartz jobs that
>overrides the default JNDI settings used by the JndiObjectFactoryBean
>like this (as if the job had to connect to JNDI remotely):
>
> <!-- JNDI connection information -->
> <bean id=3D"myJndiTemplate"
>class=3D"org.springframework.jndi.JndiTemplate">
> <property name=3D"environment">
> <props>
> <prop
>key=3D"java.naming.factory.initial">com.ibm.websphere.naming.WsnInitialC=
ontextFactory</prop>
> <prop
>key=3D"java.naming.provider.url">iiop://localhost:9091</prop>
> <prop key=3D"java.naming.security.credentials">user</prop>
> <prop key=3D"java.naming.security.principal">pw</prop>
> </props>
> </property>
> </bean>
>
> <!-- QUEUE CONNECTION FACTORY -->
> <bean id=3D"jmsQueueConnectionFactory"
> class=3D"org.springframework.jndi.JndiObjectFactoryBean"
> lazy-init=3D"true">
> <property name=3D"inContainer">
> <value>false</value>
> </property>
> <property name=3D"jndiTemplate">
> <ref local=3D"myJndiTemplate"/>
> </property>
> <property name=3D"jndiName">
> <value>Example/QueueConnectionFactory</value>
> </property>
> </bean>
>
>This also requires us to load a separate application context for the
>Quartz jobs that uses these settings, rather than being able to share
>the application context used by the rest of the application.
>
>Have you ever run into this issue? Do your support classes get around
>this somehow?
>
>Regards,
>Daniel
>
>On Wed, Feb 18, 2004 at 11:43:14PM +0100, j?rgen h?ller [werk3AT] wrote:
> =20
>
>>Everybody,
>>
>>I've revived my Quartz support classes for Spring today. They emerged f=
rom a job scheduling consulting project I did in autumn 2003. We have con=
crete needs for this now at werk3AT, thus the revival: It's about quite s=
imple cron-style scheduling of application jobs.
>>
>>The basic idea is to set up a Quartz Scheduler via a SchedulerFactoryBe=
an, also allowing to register scheduled jobs there via a <list> of <refs>=
to ScheduledJobDefinition beans. A ScheduledJobDefinition is just a simp=
le combination of a Quartz JobDetail and a Quartz Trigger.
>>
>>ScheduledJobDefinition bean implementations include:
>>- DefaultScheduledJobDefinition, allowing to use any implementation of =
Quartz' Job interface with a declaratively configured job data map and cr=
on trigger
>>- MethodInvokingJobDefinition, allowing to specify a method of a Spring=
-managed bean to execute as job (completely declarative, without the need=
for implementing a custom Job object), with a cron trigger.
>>
>>Both job definition beans can link in a separate Quartz Trigger instanc=
e instead of a cron expression; DefaultScheduledJobDefinition can also li=
nk in a separate Quartz JobDetail instance instead of a job class.
>>
>>That's all there is: A simple declarative way of using Quartz within Sp=
ring. Typically no rescheduling or the like: All schedules are set up on =
context startup, defined as bean definitions. Of course, you can also fet=
ch the Scheduler instance and perform any custom scheduling, instead of u=
sing preconfigured ScheduledJobDefinition beans.
>>
>>The typical usage scenario are low-level jobs within an application, li=
ke data synchronization or storage cleanup - all predefined jobs that are=
just customized by an administrator. Fits nicely into Spring's applicati=
on context model; most jobs will simply delegate to Spring-managed busine=
ss objects.
>>
>>I expect to have this polished by the end of the week, as we need it at=
werk3AT quite urgently. I'd like to include this already in Spring 1.0 f=
inal, as it's just 6 pretty simple classes (yes, I know - feature freeze =
- never mind ;-). The main question is where to put it: I suggest "org.sp=
ringframework.scheduling.quartz".
>>
>>If there are no general objections, I'll commit it by the end of this w=
eek, for review within the next week - still plenty of time before 1.0 fi=
nal ;-) Looking forward to your feedback!
>>
>>Juergen
>> =20
>>
|