Is it possible to specify the fixed delay interval or the cron interval pattern through some custom properties when deployed on web sphere. Currently, in my configuration the fixed delay interval is specified on the application context xml file. However, this file will get packaged in an EAR and a change to interval would require application redeployment.
Here is my app context file:
<bean id="taskScheduler" class="org.springframework.scheduling.commonj.TimerManagerTaskScheduler">
<property name="timerManager" ref="timerManager" />
</bean>
<bean id="taskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
<property name="workManager" ref="workManager" />
</bean>
<task:scheduled-tasks scheduler="taskScheduler">
<task:scheduled ref="transactionProcessingService" method="processTransactions" fixed-delay="30000"/>
<task:scheduled ref="transactionProcessingService" method="processOrderTransactions" fixed-delay="50000"/>
</task:scheduled-tasks>
Thanks for your suggestions.
Add the following in your application context
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:sample.properties"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="ignoreResourceNotFound" value="true"/>
<property name="order" value="0"/>
</bean>
Your sample.properties file
process_transactions = 30000
processOrder_transactions = 3000
Replace the following with your code.
<task:scheduled-tasks scheduler="taskScheduler">
<task:scheduled ref="transactionProcessingService" method="processTransactions" fixed-delay="${process_transactions}"/>
<task:scheduled ref="transactionProcessingService" method="processOrderTransactions" fixed-delay="${processOrder_transactions}"/>
</task:scheduled-tasks>
You can use <util:properties /> tag for loading properties from files:
Move your values to some property file (for example app.properties)
process_transactions=30000
process_order_transactions=3000
load them via properties tag from util namespace (do not forget to declare util namespace)
<util:properties id="appConfig" location="classpath:app.properties" />
set them using ${variable}syntax:
<task:scheduled-tasks scheduler="taskScheduler">
<task:scheduled ... fixed-delay="${process_transactions}"/>
<task:scheduled ... fixed-delay="${process_order_transactions}"/>
</task:scheduled-tasks>
EDIT. As explained by #user320587 we can override application property value by using JVM Custom properties in Websphere (and avoid redeploiment):
By using this along with the systemPropertiesModeName property
available in the PropertyPlaceHolderConfigurer, we could avoid
redeployment. I have set the property values as part of JVM Custom
properties in Websphere and the substitution happens when the
application is started. So, to change the interval value, I can modify
the custom property value and restart the application.
Related
I’m using Spring 3.2.11.RELEASE. I currently have the following set up in my application context file for the purposes of loading a cron trigger based off a schedule defined in a properties file (the property = cron.schedule) …
<bean id="localPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:application.properties</value>
</property>
</bean>
…
<bean id="updateResourcesJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="myService" />
<property name="targetMethod" value="myMethod" />
<property name="concurrent" value="true" />
</bean>
<bean id="updateResourcesCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="myJob" />
<property name="cronExpression" value="${cron.schedule}" />
</bean>
My question is, I would like to create an XML configuration in my context file that allows me to edit my properties file and have everything automatically reloaded without having to restart my server or re-deploy my application. I have read several places about Apache Commons Configuration, but I can’t figure out how to take the above and rewrite an XML config that would utilize the configuration.
Thanks for any help, - Dave
I'm writing to a CSV file and using FlatFileItemWriter to do it. I have a bean with that as my class, and I also have a property for the resource, where I provide the file name to use to write out the item.
Is it possible to append the date and time to the file name?
Right now I am telling it to write out to a file called report.csv, instead I want it to write out to a file called report-7-2-2014-16-03.csv
Here's the XML Config for the writer
<bean id="csvWriter" class="org.springframework.batch.item.file.FlatFileItemWriter">
<property name="resource">
<bean class="org.springframework.core.io.FileSystemResource">
<constructor-arg value="${REPORT_FILENAME}" />
</bean>
</property>
<property name="shouldDeleteIfExists" value="true" />
<property name="lineAggregator">
<bean class="com.example.CSVLineAggregator" />
</property>
<property name="headerCallback">
<bean class="com.example.CSVHeaderWriter" >
<constructor-arg value="${REPORT_HEADER}" />
</bean>
</property>
</bean>
You need to configure your step with late binding to solve your problem.
Late binding allow you to evaluate an expression during job/step execution and not in a static way (during xml pasring, to be clear) using values stored in jobParameters and job or step execution context; thise contexts are available only during job/step execution!
To enable this feature:
mark your artifacts with special step="scope"
Add to jobParameters with name 'REPORT_FILENAME' and value 'report-7-2-2014-16-03.csv' (of course this value will change every time you launch the job and is your reponsibility to make it unique and create with right date/time)
use spEL with special #{jobParameters['REPORT_FILENAME']} expression to let SB extract the report name from job parameters dinamically
<bean id="csvWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
<property name="resource" value="file://report-dir/#{jobParameters['REPORT_FILENAME']}" />
<property name="shouldDeleteIfExists" value="true" />
<property name="lineAggregator">
<bean class="com.example.CSVLineAggregator" />
</property>
<property name="headerCallback">
<bean class="com.example.CSVHeaderWriter" >
<constructor-arg value="${REPORT_HEADER}" />
</bean>
</property>
</bean>
This is just a small example but you can read more about Late binding
I have a strange problem with my spring bean definition. My application is a multi-module thing.
At the moment I have a project named core-lib which has a spring.xml file defining a PropertyPlaceholderConfigurer like this:
<bean id="corePropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="10" />
<property name="locations">
<list>
<!-- default properties files containing ALL possible properties -->
<value>classpath:default.connection.properties</value>
<value>classpath:default.mq.properties</value>
<!-- installation specific, optional properties file containing overridden properties -->
<value>classpath:connection.properties</value>
<value>classpath:mq.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
</bean>
Second I have a depending project which has its own spring.xml file including the one from the core-lib project. Moreover it defines a second PropertyPlaceholderConfigurer like this:
<!-- import configuration from service layer -->
<import resource="classpath:spring.xml"/>
<bean id="commPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="20" />
<property name="locations">
<list>
<!-- properties files containing ALL possible properties -->
<value>classpath:processing.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
</bean>
Now I have the behavior that a bean defined in this second spring PlaceholderConfigurer can't be instantiated due to missing properties:
BeanDefinitionStoreException: Invalid bean definition with name 'commServer' defined in class path resource [comm-server.spring.xml]: Could not resolve placeholder 'comm.server.CommServer.port'
If I set a breakpoint in the PropertyPlaceholderConfigurer class it only get's triggered for the first bean instance and never for the second. Has anyone had a similar setup and can give me some advice?
Thanks,
Sebastian
There is a more comfortable way by defining a new placeholder prefix and suffix:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:configuration.properties</value>
</property>
<property name="placeholderPrefix" value="myprefix{" />
<property name="placeholderSuffix" value="}" />
</bean>
Found here: http://javalibs.blogspot.co.at/2008/04/java-spring-framework-multiple.html
OK I resolved that myself, although I do not understand why this is working so strange.
I have defined a different prefix in the second placeholder (?{ instead of ${) and now its working. I had expected that this would work without any special prefixes...
I've got two properties files:
environment.properties:
- project.host.db3.database.name=oracle
application.properties:
- database.name=${project.host.db3.database.name}
The first one represents the environment variables and the second one the properties to be used in a spring project, in this configuration i try to set the environment.properties but of course it doesn't work:
<bean id="systemPropertiesLoader"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}" />
<property name="targetMethod" value="putAll" />
<property name="arguments">
<util:properties location="classpath:environment.properties" />
</property>
</bean>
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
depends-on="systemPropertiesLoader">
<property name="locations">
<list>
<value>classpath:application.properties</value>
</list>
</property>
<!-- bean using database.name -->
Is it doable?, and if not, how do people have agnostic properties in their projects (like database.name), and only one file (war, jar, etc.) to be deployed?
Well, it seems it's doable for beans xml defined as long as you define your properties it like this:
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
depends-on="systemPropertiesLoader">
But if you ever try to access the properties from a servlet:
this.getClass().getClassLoader().getResourceAsStream("application.properties");
chances are you get this:
bad port configuration: ${project.host.db3.database.port}
java.lang.NumberFormatException: For input string: "${project.host.db3.database.port}"
In answer to yorkw, now i can have the same war to be deployed in several environments and configure the host with -Denvironment=development, so i can deploy a properties file for development, production, etc. and simply use:
<bean id="systemPropertiesLoader"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}" />
<property name="targetMethod" value="putAll" />
<property name="arguments">
<util:properties location="classpath:**${environment}/**environment.properties" />
</property>
</bean>
Otherwise i should have the application.properties substituted before deployment for every environment. I'm sure there are better solutions than this.
Environment: Windows server 2003, Spring 3.0, Tomcat 6
How can I reference a JNDI property inside a PropertyPlaceholderConfigurer?
Specifically, I'm using JNDI to look up a java.lang.String that represents a path to
a property file needed by my webapp
<jee:jndi-lookup id="mypropsfile1" jndi-name="myPropsFile1" resource-ref="true"/>
<jee:jndi-lookup id="mypropsfile2" jndi-name="myPropsFile2" resource-ref="true"/>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<array>
<value>how to use mypropsfile1 here ??</value>
<value>how to use mypropsfile2 here ??</value>
</array>
</property>
</bean>
My "jee:jndi-lookup"s are working AFAIK. My problem seems to be how to reference JNDI resources
inside the tag pair
Thanks in advance!
Mark
Your approach may not work Mark, this is because PropertyPlaceHolderConfigurer is a BeanFactoryPostProcessor and gets invoked at the point when the bean definitions are created, whereas the jndi lookup happens post this stage.
I saw an older Spring forum discussion item, which has a recommendation for an approach of using a jndi lookup based properties file, which may suit your needs:
I believe you will have to do something like this . I haven't tested it but basically the setLocations method in PropertyPlaceholderConfigurer takes in an array of Resource(In our case UrlResource - http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/core/io/UrlResource.html) which in turn has a constructor with the file path .
<jee:jndi-lookup id="mypropsfile1" jndi-name="myPropsFile1" default-value="file:///C:/defaultPath" resource-ref="true"/>
<jee:jndi-lookup id="mypropsfile2" jndi-name="myPropsFile2" resource-ref="true"/>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" depends-on="mypropsfile1,mypropsfile2">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<list>
<bean class="org.springframework.core.io.UrlResource">
<constructor-arg><ref bean="mypropsfile1"/></constructor-arg>
</bean>
<bean class="org.springframework.core.io.UrlResource">
<constructor-arg><ref bean="myPropsFile2"/></constructor-arg>
</bean>
</list>
</property>
</bean>
I am not sure if there is a tag called in spring . Check this http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-introduction
I do this in Spring 3 using a map as follows:
<jee:jndi-lookup id="myJndiLookup" jndi-name="com.techtrip.spring.config.myJndiLookup"></jee:jndi-lookup>
<bean id="somethingWithMap" class="com.techtrip.foo.SomethingWithMap">
<property name="propMap">
<map>
<entry key="myJndiLookup" value-ref="myJndiLookup" />
</map>
</property>
</bean>
This works fine in most cases. You may run into trouble if you use AOP or something that wraps the bean in a Proxy class even if you set eager init correctly. A solution in that case is to directly access the somethingWithMap bean from the app context when needed using:
applicationContext.getBeansOfType(type, includeNonSingletons, allowEagerInit);
*Note that this will return a Map<String, T> where you can access the bean by name.
Not exactly for a single JNDI property, this is using a Properties reference instead, obtained through JNDI:
<!-- Lookup Properties reference through JNDI -->
<jee:jndi-lookup id="config-properties" jndi-name="resources/resource-name" resource-ref="true"/>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" depends-on="config-properties">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<!-- Once the reference is obtained from JNDI, it can be used like any other reference -->
<property name="properties" ref="config-properties"></property>
</bean>