4

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:

  1. The db.properties file is in the correct location.
  2. The credentials in the db.properties are correct, and can be read in manually to connect to the database.
  3. 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.

Oliver Drotbohm
  • 80,157
  • 18
  • 225
  • 211
Eric Wilson
  • 57,719
  • 77
  • 200
  • 270

5 Answers5

6

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>
Farid
  • 2,265
  • 18
  • 14
4

Drop the leading slash from your location (i.e. location="WEB-INF/db.properties" ) or better yet change it to classpath:

location="classpath:db.properties"
Chris
  • 22,923
  • 4
  • 56
  • 50
  • `classpath:db.properties` worked for me. Any chance you could explain the difference? It seemed (from the log files) that it was finding the file before. – Eric Wilson May 04 '12 at 14:12
  • 1
    It turns out that this helped me because I had made a copy of db.properties and was editing the wrong one. – Eric Wilson May 04 '12 at 19:59
1

use org.springframework.jdbc.datasource.DriverManagerDataSource instead of org.apache.commons.dbcp.BasicDataSource

Eric Wilson
  • 57,719
  • 77
  • 200
  • 270
creativeby
  • 859
  • 6
  • 10
0

Use ignore-unresolvable="true" in you application context. Default value is 'fales' you need to set it 'true' so pass on the key to any others in the context that have not yet visited.

<context:property-placeholder ignore-unresolvable="true" location="/WEB-INF/application.properties" />
<context:property-placeholder ignore-unresolvable="true" location="/WEB-INF/dbcp.properties"/>
0

Make sure you have the maven dependency properly, Sping-core and Spring-context dependencies should be present in your project.

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version></version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version></version>
        </dependency>
Sundar
  • 1