Announcement Announcement Module
Collapse
No announcement yet.
context:property-placeholder not working Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • context:property-placeholder not working

    Ok, I'm slowly going insane here. I've used this in multiple Spring projects and it has always worked, but with 3.1.0 and 3.1.1 I simply cannot get it to work no matter what I try.

    Spring Config:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:tx="http://www.springframework.org/schema/tx"
      xmlns:cache="http://www.springframework.org/schema/cache"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:jaxws="http://cxf.apache.org/jaxws"
      xmlns:p="http://www.springframework.org/schema/p"
      xmlns:task="http://www.springframework.org/schema/task"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-3.1.xsd
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
               http://www.springframework.org/schema/tx
               http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
               http://www.springframework.org/schema/cache
               http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
               http://www.springframework.org/schema/task
               http://www.springframework.org/schema/task/spring-task-3.1.xsd"
      default-autowire="byName">
    
      <context:property-placeholder location="classpath:database.properties" />
      <context:component-scan base-package="com.foo.bar" />
    
      <aop:aspectj-autoproxy proxy-target-class="false" />
    
      <context:annotation-config />
      
      <tx:annotation-driven transaction-manager="transactionManager" mode="aspectj" />  
      
      <task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
      <task:executor id="myExecutor" pool-size="5"/>
      <task:scheduler id="myScheduler" pool-size="10"/>
      
      <!-- ******************************************************** -->
      <!-- *** Caching ******************************************** -->
      <!-- ******************************************************** -->
      
      <cache:annotation-driven mode="aspectj" proxy-target-class="false" cache-manager="cacheManager" />
    
      <bean id="cacheManager" 
        class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache" />
      <bean id="ehcache" 
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
        p:config-location="classpath:ehcache.xml" />
      
      <!-- ******************************************************** -->
      <!-- *** Definition of the data source ********************** -->
      <!-- ******************************************************** -->
      
      <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${db.driver}" />
        <property name="jdbcUrl" value="${db.url}" />
        <property name="user" value="${db.user}" />
        <property name="password" value="${db.password}" />
      </bean>
    
      <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource">
          <ref bean="dataSource" />
        </property>
      </bean>
    
      <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
      </bean>
    
    	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
      	<property name="dataSource" ref="dataSource" />
      	<property name="configLocation" value="/WEB-INF/mybatis.xml" />
      	<property name="mapperLocations" value="classpath*:com/sonydadc/management/security/maps/**/*.xml" />
    	</bean>
    
      <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.foo.bar.daos" />
      </bean>
    
    </beans>
    The file exists. It can be read, and is found by Spring. It is shown to be loaded in the log. It finds all the properties -- I've renamed both the file and the properties to something invalid, and gotten the correct errors for that. Then, this happens:

    Code:
    [2012-02-17 14:00:15] INFO    o.s.b.f.xml.XmlBeanDefinitionReader      - Loading XML bean definitions from ServletContext resource [/WEB-INF/applicationContext.xml]
    [2012-02-17 14:00:19] INFO    o.s.c.s.PropertySourcesPlaceholderConfigurer - Loading properties file from class path resource [database.properties]
    [2012-02-17 14:00:19] INFO    o.s.s.concurrent.ThreadPoolTaskExecutor  - Initializing ExecutorService 
    [2012-02-17 14:00:19] INFO    o.s.w.c.support.XmlWebApplicationContext - Bean 'myExecutor' of type [class org.springframework.scheduling.config.TaskExecutorFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    [2012-02-17 14:00:19] INFO    o.s.w.c.support.XmlWebApplicationContext - Bean 'myExecutor' of type [class org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    [2012-02-17 14:00:19] INFO    o.s.s.concurrent.ThreadPoolTaskScheduler - Initializing ExecutorService  'myScheduler'
    [2012-02-17 14:00:19] INFO    o.s.w.c.support.XmlWebApplicationContext - Bean 'myScheduler' of type [class org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    [2012-02-17 14:00:19] INFO    o.s.b.f.s.DefaultListableBeanFactory     - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@163a582: defining beans [org.springframework.context.support.PropertySourcesPlaceholderConfigurer#0,division,sessionCache,adminServlet,chartingServlet,reportingServlet,actionHelper,adminHelper,authorizationHelper,chartingHelper,contextHelper,customerHelper,daoLoggingPointcut,downloadHelper,emailHelper,incidentHelper,locationHelper,logHelper,meetingHelper,profileHelper,reportHelper,reportingHelper,securityExceptionHelper,securityExceptionJob,textHelper,userHelper,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.config.internalTransactionAspect,org.springframework.context.annotation.internalAsyncAnnotationProcessor,org.springframework.context.annotation.internalScheduledAnnotationProcessor,myExecutor,myScheduler,org.springframework.cache.config.internalCacheAspect,cacheManager,ehcache,dataSource,jdbcTemplate,transactionManager,sqlSessionFactory,org.mybatis.spring.mapper.MapperScannerConfigurer#0,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0,actionDao,chartingDao,customerDao,incidentDao,locationDao,meetingDao,NSPDao,profileDao,reportDao,resourcesDao,securityExceptionDao,userDao,utilityDao]; root of factory hierarchy
    [2012-02-17 14:00:21] INFO    o.s.c.ehcache.EhCacheManagerFactoryBean  - Initializing EHCache CacheManager
    [2012-02-17 14:00:21] INFO    o.s.web.context.ContextLoader            - Root WebApplicationContext: initialization completed in 7555 ms
    [2012-02-17 14:00:21] DEBUG   c.s.m.security.util.SecurityExceptionJob - Executing updateActive for security exceptions...
    Feb 17, 2012 2:00:22 PM org.apache.catalina.core.ApplicationContext log
    Information: Initializing Spring FrameworkServlet 'MvcServlet'
    [2012-02-17 14:00:22] INFO    o.s.web.servlet.DispatcherServlet        - FrameworkServlet 'MvcServlet': initialization started
    [2012-02-17 14:00:22] INFO    o.s.w.c.support.XmlWebApplicationContext - Refreshing WebApplicationContext for namespace 'MvcServlet-servlet': startup date [Fri Feb 17 14:00:22 CET 2012]; parent: Root WebApplicationContext
    JRebel-Spring: Monitoring Spring bean definitions in 'D:\STS\workspace\DADC_Corporate_Security_Reporting\WebRoot\WEB-INF\mvcServletContext.xml'.
    [2012-02-17 14:00:22] INFO    o.s.b.f.xml.XmlBeanDefinitionReader      - Loading XML bean definitions from ServletContext resource [/WEB-INF/mvcServletContext.xml]
    [2012-02-17 14:00:22] WARN    c.m.v2.c3p0.DriverManagerDataSource      - Could not load driverClass ${jdbc.driverClassName}
    java.lang.ClassNotFoundException: ${db.driver}
    No matter what I try, this keeps happening. What's going on here? Thanks in advance.

    (There's a second spring config for the MVC servlet, but it uses no substitutions)

  • #2
    It looks like the definition is loaded twice next to that could it be related to JRebel due to some of the dynamicness it adds?

    Comment


    • #3
      I disabled JRebel and the result was the same.

      Comment


      • #4
        Well then you must be loading your configuration again and are probably overriding the existing PPHC... Either that or your properties file is not correct.

        Comment


        • #5
          When I turn off JRebel it loads only once, but still doesn't work. The properties file ... I don't even know what could be incorrect; surely Spring would complain if it were. Also, if I rename db.driver to db.fake, Spring says it can't find that property to replace, so it's correctly parsing the properties file and seeing the replacements.

          Comment


          • #6
            Why should it complain it doesn't know if something is wrong if you mistype something it is just a property. Post the content of your properties file and maybe your full configuration... It goes haywire if you load the servlet hence my suggestion of you loading the configuration twice and the second time overriding the PPHC...

            Comment


            • #7
              That is my full configuration in applicationContext.xml. I have a second context file:

              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <beans xmlns="http://www.springframework.org/schema/beans"
                xmlns:aop="http://www.springframework.org/schema/aop"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xmlns:tx="http://www.springframework.org/schema/tx"
                xmlns:cache="http://www.springframework.org/schema/cache"
                xmlns:context="http://www.springframework.org/schema/context"
                xmlns:jaxws="http://cxf.apache.org/jaxws"
                xmlns:p="http://www.springframework.org/schema/p"
                xmlns:mvc="http://www.springframework.org/schema/mvc"
                xsi:schemaLocation="http://www.springframework.org/schema/beans
                         http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                         http://www.springframework.org/schema/context
                         http://www.springframework.org/schema/context/spring-context-3.1.xsd
                         http://www.springframework.org/schema/aop
                         http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
                         http://www.springframework.org/schema/tx
                         http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
                         http://www.springframework.org/schema/cache
                         http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
                         http://www.springframework.org/schema/mvc
                         http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd"
                default-autowire="byName">
                
                <context:annotation-config />
                <context:component-scan base-package="com.foo.bar" />
                
                <mvc:annotation-driven>
                  <mvc:argument-resolvers>
                    <bean class="org.springframework.mobile.device.DeviceWebArgumentResolver" />
                    <bean class="org.springframework.mobile.device.site.SitePreferenceWebArgumentResolver" />        
                  </mvc:argument-resolvers>  
                </mvc:annotation-driven>
              
              	<mvc:interceptors>
              	  <bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor" />
              	  <bean class="org.springframework.mobile.device.site.SitePreferenceHandlerInterceptor" />
              	</mvc:interceptors>
                
              	<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
                  <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
                </bean>
              	<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
                  <property name="definitions">
                    <list>
                      <value>/WEB-INF/tiles.xml</value>
                    </list>
                  </property>
                </bean>
                
              </beans>
              and here's database.properties:

              Code:
              db.driver=oracle.jdbc.driver.OracleDriver
              db.url=jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=xxxxxx)(Port=1535))(CONNECT_DATA=(SERVICE_NAME=XXXXXX)))
              db.user=XXXXXX
              db.password=XXXXXX

              Comment


              • #8
                At least one problem is that you have bean duplication, both xml files scan for the same components next to that you don't need context:annotation-config (that is implied by component-scan). Another pointer (not related to your problem) use the TilesViewResolver saves you a couple of lines of xml.

                Back to your problem it seems as if the datasource is getting initialized for a second time and before the BeanFactoryPostProcessor has done its work. So why is it triggering a reload and whyis it trying to get the datasource before it is processed.

                Comment


                • #9
                  Just created an unit test only loading the first file, same problem. Thanks for the other pointers, though, I'll check that out.

                  The TimerTask uses the database and gets a helper injected. Could that be the problem?

                  EDIT: No, it's not, I just took it out and same result.

                  Comment


                  • #10
                    Didn't see a timertask in the configuration but alas. You could try and enable DEBUG logging to see what happens in more detail. In general if your placeholders don't get replaced it is used before the container is being post processed so it might be used by a post processor itself or (unknowningly) by one of the namespace configuration things.

                    A workaround I used in these cases (at least if the datasource isn't needed at startup time) is to do a lookup instead of injection, ie. make the concerning bean BeanFactoryAware and when needed pull the bean out of the factory (this is more or less circumenventing the eager initialization issue).

                    Comment


                    • #11
                      Debug logging also shows it's found (I've renamed the property in the meantime, so that's not it). See last line of log:

                      Code:
                      [2012-02-17 15:04:25] DEBUG   o.s.core.env.MutablePropertySources      - Adding [environmentProperties] PropertySource with lowest search precedence
                      [2012-02-17 15:04:25] INFO    o.s.c.s.PropertySourcesPlaceholderConfigurer - Loading properties file from file [database.properties]
                      [2012-02-17 15:04:25] DEBUG   o.s.core.env.MutablePropertySources      - Adding [localProperties] PropertySource with lowest search precedence
                      [2012-02-17 15:04:25] DEBUG   o.s.c.e.PropertySourcesPropertyResolver  - Searching for key 'jdbc.driverClassName' in [environmentProperties]
                      [2012-02-17 15:04:25] DEBUG   o.s.c.e.PropertySourcesPropertyResolver  - Searching for key 'jdbc.driverClassName' in [servletConfigInitParams]
                      [2012-02-17 15:04:25] DEBUG   o.s.c.e.PropertySourcesPropertyResolver  - Searching for key 'jdbc.driverClassName' in [servletContextInitParams]
                      [2012-02-17 15:04:25] DEBUG   o.s.c.e.PropertySourcesPropertyResolver  - Searching for key 'jdbc.driverClassName' in [jndiProperties]
                      [2012-02-17 15:04:25] DEBUG   org.springframework.jndi.JndiTemplate    - Looking up JNDI object with name [java:comp/env/jdbc.driverClassName]
                      [2012-02-17 15:04:25] DEBUG   o.s.jndi.JndiLocatorDelegate             - Converted JNDI name [java:comp/env/jdbc.driverClassName] not found - trying original name [jdbc.driverClassName]. javax.naming.NameNotFoundException: Name jdbc.driverClassName is not bound in this Context
                      [2012-02-17 15:04:25] DEBUG   org.springframework.jndi.JndiTemplate    - Looking up JNDI object with name [jdbc.driverClassName]
                      [2012-02-17 15:04:25] DEBUG   o.s.jndi.JndiPropertySource              - JNDI lookup for name [jdbc.driverClassName] threw NamingException with message: Name jdbc.driverClassName is not bound in this Context. Returning null.
                      [2012-02-17 15:04:25] DEBUG   o.s.c.e.PropertySourcesPropertyResolver  - Searching for key 'jdbc.driverClassName' in [systemProperties]
                      [2012-02-17 15:04:25] DEBUG   o.s.c.e.PropertySourcesPropertyResolver  - Searching for key 'jdbc.driverClassName' in [systemEnvironment]
                      [2012-02-17 15:04:25] DEBUG   o.s.c.e.PropertySourcesPropertyResolver  - Could not find key 'jdbc.driverClassName' in any property source. Returning [null]
                      [2012-02-17 15:04:25] DEBUG   o.s.c.e.PropertySourcesPropertyResolver  - Searching for key 'jdbc.driverClassName' in [localProperties]
                      [2012-02-17 15:04:25] DEBUG   o.s.c.e.PropertySourcesPropertyResolver  - Found key 'jdbc.driverClassName' in [localProperties] with type [String] and value 'oracle.jdbc.driver.OracleDriver'
                      
                      EDIT: it later initializes a bunch more standard environments (3 or 4 times) without that file present, but at that point, the property is already found!
                      Last edited by gschmidl; Feb 17th, 2012, 09:11 AM.

                      Comment

                      Working...
                      X