|
From: Colin S. <col...@ex...> - 2004-02-25 04:23:56
|
Juergen,
Further to this, I noticed you changed the 'args' property to 'arguments'. For me personally this is not that big a deal (I've alrady made the change in my configs), but do you think it's really worth breaking backwards compatibility for this? Args is a well known and used abbreviation for arguments. I wouldn't say the latter is so much better than the former that it's worth breaking people's config, now that the code already shipped with the name args...
Regards,
Colin
jürgen höller [werk3AT] wrote:
>Good point - I'll re-add "staticMethod" as convenience setter!
>
>
>________________________________
>
>Von: spr...@li... im Auftrag von Colin Sampaleanu
>Gesendet: Do 19.02.2004 21:54
>An: spr...@li...
>Betreff: Re: [Springframework-developer] Quartz support
>
>
>
>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
>because the same property is used for specifyng the method name as for
>the non-static case, but on the other hand, static methods are probably
>one of the most common uses of this class, and you've turned a one
>property config into a two property config, i.e.
> <bean id="qa-util-initProfileImpl"
>class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
> <property
>name="staticMethod"><value>com.whatever.qaserver.device.ProfileClassesInit.initProfileClasses</value></property>
> </bean>
>tnow becomes
> <bean id="qa-util-initProfileImpl"
>class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
> <property
>name="targetMethod"><value>initProfileClasses</value></property>
> <property
>name="targetClass"><value>com.whatever.qaserver.device.ProfileClassesInit</value></property>
> </bean>
>
>As well, this also breaks backwards compatibility for anybody using it.
>Perhaps you can add back the
> staticMethod
>property, and on a set, the code inside it would break up the supplied
>string into calls to setTargetMethod and setTargetClass (it would have
>to create the class itself).
>
>This would allow both forms to be used, and keep backwards compatibility...
>
>Regards,
>Colin
>
>jürgen höller [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!
>>
>>Juergen
>>
>>
>>________________________________
>>
>>Von: spr...@li... im Auftrag von jürgen höller [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 with container-managed threads; unfortunately, this does not apply to Quartz threads.
>>
>>However, there's a strategy that should work: pre-locate the JNDI objects, 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, not 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 register JobDetails, Calendars and Triggers with it
>>
>>- convenience subclasses of JobDetail, CronTrigger and SimpleTrigger that allow for easy bean-style usage; the latter allow for implicit registration of an associated JobDetail
>>
>>- a FactoryBean for a JobDetail that invokes a method of an existing object, 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 data map entries as bean properties
>>
>>A configuration example:
>>
>> <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
>> <property name="triggers">
>> <list>
>> <ref bean="myTrigger1"/>
>> <ref bean="myTrigger2"/>
>> </list>
>> </property>
>> </bean>
>>
>> <bean id="myJobDetail1" class="org.springframework.scheduling.quartz.JobDetailBean">
>> <property name="jobClass"><value>werk3.example.MyJob</value></property>
>> <property name="jobDataAsMap">
>> <map>
>> <entry key="testBean">
>> <bean class="org.springframework.beans.TestBean">
>> <property name="age"><value>99</value></property>
>> </bean>
>> </entry>
>> </map>
>> </property>
>> </bean>
>>
>> <bean id="myJobDetail2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
>> <property name="targetObject"><ref bean="exampleService"/></property>
>> <property name="targetMethod"><value>doSomething</value></property>
>> </bean>
>>
>> <bean id="myTrigger1" class="org.springframework.scheduling.quartz.CronTriggerBean">
>> <property name="jobDetail"><ref bean="myJobDetail1"/></property>
>> <property name="cronExpression"><value>0/5 * * * * ?</value></property>
>> </bean>
>>
>> <bean id="myTrigger2" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
>> <property name="jobDetail"><ref bean="myJobDetail2"/></property>
>> <property name="repeatInterval"><value>1000</value></property>
>> </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 = testBean;
>> }
>>
>> protected void executeInternal(JobExecutionContext jobExecutionContext) {
>> System.out.println("Executing job..." + testBean.getAge());
>> }
>> }
>>
>>Note that the "testBean" entry in the job data map is automatically applied as bean property in MyJob.
>>
>>As a side note, I've refactored Colin's MethodInvokingFactoryBean into org.springframework.util.MethodInvoker, with MethodInvokingFactoryBean and MethodInvokingJobDetailFactoryBean as subclasses. They provide exactly the 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 it'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="myJndiTemplate"
>>class="org.springframework.jndi.JndiTemplate">
>> <property name="environment">
>> <props>
>> <prop
>>key="java.naming.factory.initial">com.ibm.websphere.naming.WsnInitialContextFactory</prop>
>> <prop
>>key="java.naming.provider.url">iiop://localhost:9091</prop>
>> <prop key="java.naming.security.credentials">user</prop>
>> <prop key="java.naming.security.principal">pw</prop>
>> </props>
>> </property>
>> </bean>
>>
>> <!-- QUEUE CONNECTION FACTORY -->
>> <bean id="jmsQueueConnectionFactory"
>> class="org.springframework.jndi.JndiObjectFactoryBean"
>> lazy-init="true">
>> <property name="inContainer">
>> <value>false</value>
>> </property>
>> <property name="jndiTemplate">
>> <ref local="myJndiTemplate"/>
>> </property>
>> <property name="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:
>>
>>
>>
>>
>>>Everybody,
>>>
>>>I've revived my Quartz support classes for Spring today. They emerged from a job scheduling consulting project I did in autumn 2003. We have concrete needs for this now at werk3AT, thus the revival: It's about quite simple cron-style scheduling of application jobs.
>>>
>>>The basic idea is to set up a Quartz Scheduler via a SchedulerFactoryBean, also allowing to register scheduled jobs there via a <list> of <refs> to ScheduledJobDefinition beans. A ScheduledJobDefinition is just a simple 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 cron 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 instance instead of a cron expression; DefaultScheduledJobDefinition can also link in a separate Quartz JobDetail instance instead of a job class.
>>>
>>>That's all there is: A simple declarative way of using Quartz within Spring. Typically no rescheduling or the like: All schedules are set up on context startup, defined as bean definitions. Of course, you can also fetch the Scheduler instance and perform any custom scheduling, instead of using preconfigured ScheduledJobDefinition beans.
>>>
>>>The typical usage scenario are low-level jobs within an application, like data synchronization or storage cleanup - all predefined jobs that are just customized by an administrator. Fits nicely into Spring's application context model; most jobs will simply delegate to Spring-managed business 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 final, 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.springframework.scheduling.quartz".
>>>
>>>If there are no general objections, I'll commit it by the end of this week, for review within the next week - still plenty of time before 1.0 final ;-) Looking forward to your feedback!
>>>
>>>Juergen
>>>
>>>
>>>
|