Spring 3.2 and Quartz Scheduler - spring

I have an Spring application to maintain that has Quartz Scheduler configured in an applicationContex-quartz.xml file. A SchedulerFactoryBean is defined with a list of 4 triggers.
One of the triggers i have to modify is a CronTrigger with a simple schedule where it's ran the 15th of the month at 3AM. I need to take into account of some special holidays. I'm aware i can use the Calendar class. My question really is how do I configure it in the xml file? I only want one of the triggers to use it.
Thanks

If those special holidays can be expressed into a single cron expression you shouldn't have problems.
If those special holidays can't be expressed into a single cron expression and you don't want to modify the following:
<bean id="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger1" />
<ref bean="cronTrigger2" />
<ref bean="cronTrigger3" />
<ref bean="cronTrigger4" />
</list>
</property>
I think you can't do what you want because in a CronTriggerBean:
<bean id="cronTrigger1" ="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="quartzSchedulerSpecialHolidays" />
<property name="cronExpression" value="abracadabra" />
</bean>
you can associate only one jobDetail to one cronExpression.

Related

MethodInvokingFactoryBean returns itself instead of desired object

I am trying to use a MethodInvokingFactoryBean to get an instance of a com.amazonaws.regions.Region for use in configuring a com.amazonaws.services.kinesis.AmazonKinesisClient. I am doing this in Blueprint, Camel, Karaf.
<bean id="awsRegion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="com.amazonaws.regions.RegionUtils"/>
<property name="targetMethod" value="getRegion"/>
<property name="arguments">
<list>
<value>EU-WEST-1</value>
</list>
</property>
</bean>
<bean id="kinesisClient" class="com.amazonaws.services.kinesis.AmazonKinesisClient">
<property name="region" ref="awsRegion"/>
</bean>
This seems like it should work, with the first bean creating a Region, and the second bean using it.
However, I get an error that makes it seem like the MethodInvokingFactoryBean is just returning an instance of itself instead of Region.
org.osgi.service.blueprint.container.ComponentDefinitionException: Error setting property: PropertyDescriptor <name: region, getter: null, setter: [class com.amazonaws.AmazonWebServiceClient.setRegion(class com.amazonaws.regions.Region)]
...
Caused by: java.lang.Exception: Unable to convert value org.springframework.beans.factory.config.MethodInvokingFactoryBean#2289c050 to type com.amazonaws.regions.Region
The method I'm invoking in RegionUtils should return a Region
https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/regions/RegionUtils.html#getRegion-java.lang.String-
I came upon this way of getting the Region in the Client in this question, where the solution seemed to work for the asker.
Bind aws sqs region camel
At first , apache-camel tag is excess here. As second, you missed that asker is using spring context and you are using blueprint context. Try something like this:
<bean id="awsRegion" class="com.amazonaws.regions.RegionUtils" factory-method="getRegion">
<argument value="EU-WEST-1"/>
</bean>
<bean id="kinesisClient" class="com.amazonaws.services.kinesis.AmazonKinesisClient">
<property name="region" ref="awsRegion"/>
</bean>
EDIT: just tested this example with latest aws-java-sdk and it is worked

how to initialize static data member using spring with out creating object of it

<bean name="staticHubInitializer" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="very.public.api.StaticHub.setInstance"/>
<property name="arguments">
<list>
<ref bean="myPrecious"/>
</list>
</property>
</bean>
as i know spring ioc container create a bean MethodInvokingFactoryBean then it calls the setInstance() with parameter myPrecious just want a clarification is there any way we can suggest that dont create a object of it call directly ???
or is there any other way we can invoke the data member and assign the value to it directly.

How to avoid hardcoded names in DelimitedLineTokenizer names?

I am using DelimitedLineTokenizer to read from a txt file using FlatFileItemReader. However, is there a way to avoid hardcoding the "names" property of the fields ? Instead can we use any bean ?
<bean id="employeeReader" class="org.springframework.batch.item.file.FlatFileItemReader"
scope="step">
<property name="resource" value="#{jobParameters['input.file.name']}" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="empId,empName,empAge" />
</bean>
</property>
<property name="fieldSetMapper">
<bean
class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="targetType" value="com.example.Employee" />
</bean>
</property>
</bean>
</property>
</bean>
Currently there is not because the result of the LineTokenizer's work is a FieldSet. A FieldSet is like a ResultSet for a file. So just like in a ResultSet, we need to reference each "column" by something which in this case is the name. The LineTokenizer has no insight into where the data is ending up (what the object looks like) so we have no way to introspect it. If you wanted to take a more dynamic approach, you'd want to implement your own LineMapper that combines the two functions together allowing for that type of introspection.
As always, pull requests are appreciated!
In addition to Michael Minella's answer, here's what you can do :
You can use a value such as #{jobParameter['key']}, #{jobExecutionContext['key']} or #{stepExecutionContext['key']} in the <property name="names"> tag.
This means that you can have a step or a listener which does your business logic and save the result at any time in the ExecutionContext :
stepExecution.getJobExecution().getExecutionContext().put(key, value);
Keep in mind though, that the field names of a DelimitedLineTokenizer needs a String (well not really, but close enough), not a bean.

How to refer to current bean in spring expression language

I am using spring-3.2.2. I am new to spring and using the Spring Expression Language for the first time. Please consider the below snippet of spring configuration file in which I am facing the issue.
<bean id="bean3" class="com.springaction.testcollection.PersonBean">
<property name="name" value="Prakash" />
<property name="age" value="62" />
<property name="salary" value="30000" />
<property name="bonus" value="#{salary*T(PersonBean).count}" />
</bean>
In the above snippet, I want to use the salary field of the same bean(bean3) to calculate the bonus value. I just want to know how to refer the current bean's fields in the spring-configuration file? Is it possible? If not are there any alternatives to resolve the issue ?

In spring xml config,how to automatically get the current bean's ID value?

I use quartz in spring xml, I have many config like above config~~
I want to known ,automatically get the id value of the current bean
Not every time I hand-written the value of the current bean!!
<bean id="openBaiduTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<bean p:targetObject-ref="baiduManager" p:targetMethod="createOpenBaiDu" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" />
</property>
<property name="cronExpression" value="#{p_schedule['openBaiduTrigger.cronExpression']}" />
</bean>

Resources