Spring dataSource bean definition failing
datasource, java, jdbc, spring
Solution
You probably have multiple `<context:property-placeholder ... >` in your project which each create a new instance of the underlying object, and is a doorway to pains...
I prefer using the following declaration for loading property files:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db-config.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
Problem
I'm trying to use Spring's JdbcTemplate to simplify my DAOs in a Java web service that is deployed in Tomcat and connects to Postgres. I'm following Spring's documention, and I'm trying configure a DataSource in the application context file, as follows: ``` <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.manta" /> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driverClassName}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </bean> <context:property-placeholder location="/WEB-INF/db.properties"/> </beans> ``` I have the following `db.properties` file in the appropriate place: ``` driverClassName=org.postgresql.Driver url=jdbc:postgresql://pgprod.ecnext.com:5432/manta username=my_user_name password=my_password ``` When I try to deploy, I find the following stack trace in `catalina.out`: ``` SEVERE: Context initialization failed org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'dataSource' defined in ServletContext resource [/WEB-INF/context.xml]: Could not resolve placeholder 'driverClassName' at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:209) at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.processProperties(PropertyPlaceholderConfigurer.java:220) at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:84) at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:681) at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:656) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:446) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4765) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5260) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:866) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:842) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:958) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1599) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) at java.util.concurrent.FutureTask.run(FutureTask.java:166) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:679) ``` Things that are NOT the problem: - The `db.properties` file is in the correct location. - The credentials in the `db.properties` are correct, and can be read in manually to connect to the database. - The `context.xml` file is being found by the ContextLoaderListener, and I am able to inject other dependencies. I would very much appreciate any suggestions as to what could cause this. I'm using Spring 3.1.1, and Tomcat 7.0.26.