Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Spring @Scheduled: problems in getting cron expression from properties file

  1. #1
    Join Date
    May 2009
    Posts
    23

    Default Spring @Scheduled: problems in getting cron expression from properties file

    Hi all

    First of all I wish you and your beloved all the best for this Christmass and a wonderful happy new year

    Now...In my project I'm using spring 3.1.1 and I need to execute some scheduled jobs
    I used spring-batch for the job stuffs then I used the spring's @Scheduled annotation in order to execute them and all works pretty good
    Next step is that I want to configure the @Scheduled cron expression in a properties file and I'm having some problems

    The project is composed by several sub-modules; each sub-module is a separate maven artifact (and, obviously, a separate eclipse project)
    So in my case I have a sub-module where I configure the propertyplaceholder (taking inspiration by this link http://forum.springsource.org/showth...ron-expression)
    Now in this sub-module I have this configuration:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
    	xmlns="http://www.springframework.org/schema/beans" 
        xmlns:task="http://www.springframework.org/schema/task"
        xmlns:batch="http://www.springframework.org/schema/batch"
    	xsi:schemaLocation="http://www.springframework.org/schema/aop 
                            http://www.springframework.org/schema/aop/spring-aop.xsd
    		                http://www.springframework.org/schema/beans 
                            http://www.springframework.org/schema/beans/spring-beans.xsd
    		                http://www.springframework.org/schema/tx 
                            http://www.springframework.org/schema/tx/spring-tx.xsd
    		                http://www.springframework.org/schema/context 
                            http://www.springframework.org/schema/context/spring-context.xsd 
                            http://www.springframework.org/schema/task 
                            http://www.springframework.org/schema/task/spring-task.xsd 
                            http://www.springframework.org/schema/batch
                            http://www.springframework.org/schema/batch/spring-batch.xsd">
                            
    	<context:annotation-config />
    	<tx:annotation-driven transaction-manager="jtaTransactionManager" />
        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
            <property name="ignoreResourceNotFound" value="false"/>
            <property name="locations">
                <list>
                    <value>classpath:subModuleASchduledCron.properties</value>
                </list>
            </property>
        </bean>
        <aop:aspectj-autoproxy />
    </beans>
    In another project i have a configuration file with this content:

    Code:
    scheduledCronExpre=15 0 0 * * *
    In my class I have:

    Code:
    @Scheduled(cron = "${scheduledCronExpre}")	
    public void doJob(){
    //do my stuffs
    }
    Well when I try to execute this code I get this error:
    Code:
    Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'scheduledCronExpre'
    The full stacktrace is:
    Code:
    09:52:51,653 ERROR [StartMktIntelligenceBatches] Errore: Error creating bean with name 'myScheduledBean' defined in file [/dati/workspaces/indigo/SubModuleA/target/classes/it/schedulers/MyScheduledBean.class]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'scheduledCronExpre'
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myScheduledBean' defined in file [/dati/workspaces/indigo/SubModuleA/target/classes/it/schedulers/MyScheduledBean.class]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'scheduledCronExpre'
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
    	at it.poste.crs.invimall.marketing.intelligent.mktintelligence.batch.main.StartMktIntelligenceBatches.main(StartMktIntelligenceBatches.java:26)
    Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'scheduledCronExpre'
    	at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:173)
    	at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:125)
    	at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer$PlaceholderResolvingStringValueResolver.resolveStringValue(PropertyPlaceholderConfigurer.java:255)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:748)
    	at org.springframework.context.support.ApplicationContextAwareProcessor$EmbeddedValueResolver.resolveStringValue(ApplicationContextAwareProcessor.java:136)
    	at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor$1.doWith(ScheduledAnnotationBeanPostProcessor.java:145)
    	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:473)
    	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:451)
    	at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:114)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1461)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    	... 11 more
    By debugging I see that, when the spring context is loaded, the properties file is read by Spring....but then when I try to use a property of this property file the properties stored by the spring context seem to be null....
    I tried to search in all my projects if there was another declaration of PropertyPlaceholderConfigurer but I didn't find it...and this problem is killing me...
    Do you have any idead on how I can solve this issue?

    Thank you
    Angelo

  2. #2
    Join Date
    May 2009
    Posts
    23

    Default

    Hi all

    Any Idea on how I can solve this issue? I'm still fighting with this issue..and the winner is the issue

  3. #3
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    Make sure the file containing the properties is loaded. Also really make sure that there is no other PropertyPlaceHolderConfigurer configured (or a <contextroperty-placeholder/>) element. Also make sure that all your applicationcontext files are loaded in the same application context.

    Also for loading from different jar files use classpath*: instead of classpath:.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  4. #4
    Join Date
    May 2009
    Posts
    23

    Default

    Hi Marten

    Thank you for the answer
    I checked what you said
    The property file is loaded (moreover by debugging the spring context loading I arrived in the point where I can see that the file is loaded and properties are stored) and I have no other ApplicationContext starting. In fact I'm using a main class where I use a ClassPathXmlApplicationContext in order to load all the involved XML spring files. Its code is the following one:

    Code:
    ....
    public class StartBatches {
    	private static final Log logger = LogFactory.getLog(StartBatches.class.getName());
    	public static void main (String[] args) throws Exception{
    		try {
    			//Indico i file di contesto di spring da caricare
    			String[] springCtxFiles = {"moduleAAppCtx.xml","moduleBAppCtx.xml", "moduleCAppCtx.xml"};
    			//Carico il contesto di spring
    			ApplicationContext ctx = new ClassPathXmlApplicationContext(springCtxFiles);
    		} catch (Exception e) {
    			
    			logger.fatal("Errore durante la partenza dei batch; messaggio errore: "+e.getMessage(), e);
                            throw e;
    		}
    	}
    }
    When I execute the early written main the properties file is loaded only once and it seems to me the Spring classes, involved in loading the properties file, are no more called during the Spring context loading.

    I checked that there is no other PropertyPlaHolderConfigurer (and/or <contexrtroperty-placeholder />) element
    I also used classpath*: instead of classpath: but.....nothing changed .... It's so frustrating

    Any other tip I can follow?
    Thank you
    Angelo
    Last edited by angeloimm; Jan 4th, 2013 at 02:52 AM.

  5. #5
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    Replace the propertyplaceholder with contextroperty-placeholder see if that changes anything. Switching the order of yuor context files might also help.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  6. #6
    Join Date
    May 2009
    Posts
    23

    Default

    Hello Marten

    I tried as you suggested by using contextroperty-placeholder
    In detail this is my spring context file:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
    	xmlns="http://www.springframework.org/schema/beans" 
        xmlns:task="http://www.springframework.org/schema/task"
        xmlns:batch="http://www.springframework.org/schema/batch"
    	xsi:schemaLocation="http://www.springframework.org/schema/aop 
                            http://www.springframework.org/schema/aop/spring-aop.xsd
    		                http://www.springframework.org/schema/beans 
                            http://www.springframework.org/schema/beans/spring-beans.xsd
    		                http://www.springframework.org/schema/tx 
                            http://www.springframework.org/schema/tx/spring-tx.xsd
    		                http://www.springframework.org/schema/context 
                            http://www.springframework.org/schema/context/spring-context-3.0.xsd 
                            http://www.springframework.org/schema/task 
                            http://www.springframework.org/schema/task/spring-task.xsd 
                            http://www.springframework.org/schema/batch
                            http://www.springframework.org/schema/batch/spring-batch.xsd">
                            
    	<context:annotation-config />
    	<tx:annotation-driven transaction-manager="inViMallJtaTransactionManager" />
        <context:property-placeholder ignore-resource-not-found="false" location="classpath*:myProperties.properties"/>
         <bean id="sqlDV" class="org.mybatis.spring.SqlSessionFactoryBean" >
            <property name="dataSource" ref="dataSourceDV" />
        </bean>
        <bean id="myBatisAutoScanDV" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="it.common.dao" />
            <property name="sqlSessionFactory" ref="sqlDV" />
        </bean>
        <aop:aspectj-autoproxy />
    </beans>
    But I still have the error....this is making me really crazy....Any other tip I can use?

    Angelo

  7. #7
    Join Date
    May 2009
    Posts
    23

    Default

    Hello

    I tried in using the contextlaceholder but nothing changed
    I debugged the code and I see that the properties file is loaded in the class "org.springframework.core.io.support.PropertiesLoad erSupport"
    But then in no place there is an instruction like "System.setProperties....."; as far as I know (but I may be wrong) this means that in the class "org.springframework.beans.factory.config.Property PlaceholderConfigurer" when we try to execute the method "resolveSystemProperty" the obtained value will be always null since the method implementation is:
    Code:
    	protected String resolveSystemProperty(String key) {
    		try {
    			String value = System.getProperty(key);
    			if (value == null && this.searchSystemEnvironment) {
    				value = System.getenv(key);
    			}
    			return value;
    		}
    		catch (Throwable ex) {
    			if (logger.isDebugEnabled()) {
    				logger.debug("Could not access system property '" + key + "': " + ex);
    			}
    			return null;
    		}
    	}
    Am I missing anything?
    I really can't figure where I'm wrong.....
    I did a very simple thing...I modified my main class in this way:
    Code:
    ....
    public class StartBatches {
    	private static final Log logger = LogFactory.getLog(StartBatches.class.getName());
    	public static void main (String[] args) throws Exception{
    		try {
                            Resource prop = new ClassPathResource("subModuleASchduledCron.properties");
                            Properties props = new Properties();
    			props.load(prop.getInputStream());
    			Enumeration<Object> chiavi = props.keys();
    			while (chiavi.hasMoreElements()) {
    				Object object = (Object) chiavi.nextElement();
    				System.getProperties().setProperty((String)object, (String)props.get(object));
    			}
    			//Indico i file di contesto di spring da caricare
    			String[] springCtxFiles = {"moduleAAppCtx.xml","moduleBAppCtx.xml", "moduleCAppCtx.xml"};
    			//Carico il contesto di spring
    			ApplicationContext ctx = new ClassPathXmlApplicationContext(springCtxFiles);
    		} catch (Exception e) {
    			
    			logger.fatal("Errore durante la partenza dei batch; messaggio errore: "+e.getMessage(), e);
                            throw e;
    		}
    	}
    }
    Let's not see code quality...by doing this thing all works pretty good....
    I'm wondering.....is this correct? Am I doing anything wrong?

    Any suggestion is really welcome....
    Thank you
    Angelo

  8. #8
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    What is wrong with System.setProperty or System.setProperties ? (I strongly suggest the API docs).

    Also not sure what you are trying here at least why you are so focussed on the resolveSystemProperty method as your stacktrace indicates that there is no mention of that method being called. The PropertyPlaceHolder will never set system properties but will/can use that as a fallback/override to loaded properties files.

    Put a break point in the postProcessBeanFactory method of the PropertyResourceConfigurer class and see if that executes before your annotation gets parsed. If that is the case the properties should be available if not the properties aren't available and you have an ordering issue (as mentioned earlier).
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  9. #9
    Join Date
    May 2009
    Posts
    23

    Default

    Hi Marten

    My intention was not to say that there is something wrong with System.setProperty or System.setProperties (and sure I see the API docs) and I absolutly don't want to attack anyone...I'm only trying to understand where I'm wrong (because I'm pretty sure that it's something related to my configuration) and it seems to me strange that, even if the property file is loaded, the properties are not available.
    So if I gave the sensation I wanted to attack..please pardon me

    With regards to the break point in the postProcessBeanFactory method of the PropertyResourceConfigurer class...I have set it and it seems to me that this method is called before that my annotation is called (sure you are talking of the @Scheduled annotation); in fact I enter in the break point before that the batch is tried to be executed and, as I said, in the java.util.Properties object passed between the several classes my properties are present; when I try to get one of them...I get a null value.

    Regarding the ordering issue I followed this approach:
    • the first file is where my jta transaction manager is defined
    • the second file is where the PropertyPlaceholderConfigurer is defined
    • the third file is where there is the batch I want to execute


    Now I tried in this order:
    • the second file is where the PropertyPlaceholderConfigurer is defined
    • the first file is where my jta transaction manager is defined
    • the third file is where there is the batch I want to execute


    And now It seems to work.....Thank you for the support....the problem is related to the ordering...

    Cheers,

    Angelo
    Last edited by angeloimm; Jan 7th, 2013 at 05:30 AM.

  10. #10
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    With regards to the break point in the postProcessBeanFactory method of the PropertyResourceConfigurer class...I have set it and it seems to me that this method is called before that my annotation is called (sure you are talking of the @Scheduled annotation); in fact I enter in the break point before that the batch is tried to be executed and, as I said, in the java.util.Properties object passed between the several classes my properties are present; when I try to get one of them...I get a null value.
    Indeed at leat the postProcessBeanFactory method of the PRC should execute before the method parsing the @Scheduled annotation.

    However the fact that ordering is important is still a bit strange as the PropertyPlaceHolderConfigurer is a BeanFactoryPostProcessor which operates before any other postprocessors. The BeanPostProcessor should execute after that.

    The only thing I can imagine is that the BeanPostProcessor somehow gets it dependencies injected before all the BeanFactoryPostProcessors have executed or at least have influenced the EmbeddedValueResolver.

    Would it be possible for you to create a small testcase showing this probably a contextroperty-placeholder and task:annotation-driven would be enough to show this issue. When done could you register a JIRA issue...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •