I work with Spring 3.2.2 . I want to use db.properties file for DB parameters
db.properties
db.driver=org.postgresql.Driver
db.url=jdbc:postgresql://localhost:5432/test
db.user=test
db.password=test
spring configuration
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.user}"/>
<property name="password" value="${db.password}"/>
</bean>
but I have error
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'driverClassName' threw exception; nested exception is java.lang.IllegalStateException: Could not load JDBC driver class [${db.driver}]
Can anybody help me?
Try to define you property file in spring as:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:db.properties</value>
</property>
</bean>
and than access it in a same way as you did.
Related
This is a question that was asked in an interview .
The question was that a bean has certain properties which we configure in .xml file and then we inject it but let's say that one does not know that the properties or the properties will be different for different Beans . So how will we make that bean so that we are able to configure it in runtime ?
I think externalizing the bean values, something like:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:com/foo/jdbc.properties</value>
</property>
</bean>
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
then following the example having your jdbc.properties file:
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://production:9002
jdbc.username=sa
jdbc.password=root
the properties can be configured at runtime
I want to read in a properties file with my data source connection information and be able to get those values from my Spring-Datasource.xml file. Here is what I have:
Code
Properties prop = properties.load(new FileReader(fileName));
PropertySource myPropertySource = new MyPropertySource(prop);
AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[]{"/applicationContext.xml"},false);
applicationContext.getEnvironment().getPropertySources().addFirst(myPropertySource);
System.out.println(applicationContext.getEnvironment().getProperty("database.username"));
applicationContext.refresh();
This will display the correct value for database.username.
Spring-Datasource.xml
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
I end up with the following error, it does not seem to find any of the properties.
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'dataSource' defined in class path resource [Spring-Datasource-dev.xml]: Could not resolve placeholder 'database.driver'
Am I accessing them wrong, or missing something? Thanks.
You have typos... instead of this:-
<property name="username" value="%{database.username}"/>
<property name="password" value="%{database.password}"/>
... do this:-
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
If that doesn't solve the problem, then you may have forgotten to define PropertyPlaceholderConfigurer:-
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:messages.properties"/>
</bean>
If you are trying to load dynamic properties file, you can try this: PropertyPlaceholderConfigurer: can i have a dynamic location value
I am developing project using Spring3.1 and hibernate4.
Now I want to encrypt the sensitive data like username, password of database from properties file.
Here are the steps which I followed : (ref http://www.jasypt.org/spring31.html)
1.Configuring placeholder :
<bean id="propertyConfigurer" class="org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer">
<constructor-arg ref="configurationEncryptor" />
<property name="locations">
<list>
<value>/WEB-INF/classes/connection.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
2.Configuration for encryptor
<bean id="encryptorConfig" class="org.jasypt.encryption.pbe.config.SimplePBEConfig">
<property name="algorithm" value="PBEWithMD5AndDES" />
<property name="password" value="MASTERPASSWORD" />
</bean>
<bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="config" ref="encryptorConfig" />
</bean>
3.Database connection
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${data.driver}"/>
<property name="url" value="${data.url}"/>
<property name="username" value="${data.user}"/>
<property name="password" value="${data.password}"/>
</bean>
4.Generated encrypted values using jasypt by command :
encrypt input="MY_DATABASE_PASSWORD" password="MASTERPASSWORD" algorithm="PBEWithMD5ANDDES"
5.connection.properties file contains
data.user=ENC(VO0A3aXAu71CCgzGFa+nJO/7M/0b5MF2)
data.password=ENC(EogzgPllaXTDm7wq5kRp6uPmkWq6pmDV)
When I run application, I am still getting error as :
org.postgresql.util.PSQLException: FATAL: password authentication failed for user "ENC(VO0A3aXAu71CCgzGFa+nJO/7M/0b5MF2)"
These are the extra jars which I have included for integrating Spring application with jasypt:
commons-dbcp-1.1.jar
commons-lang-2.1.jar
commons-pool-1.2.jar
icu4j-3.4.4.jar
jasypt-1.9.0.jar
jasypt-1.9.0-lite.jar
jasypt-acegisecurity-1.9.0.jar
jasypt-hibernate4-1.9.0.jar
jasypt-spring3-1.9.0.jar
jasypt-spring31-1.9.0.jar
Am I missed any thing or is there any jar compatibility issue ?
Does not look like a missing jar issue.
Jasypt is unable to decrypt the username/password.
With Spring 3.1 i'd suggest the following config:
<encryption:encryptable-property-placeholder encryptor="stringEnc" propertie-ref="dbProperties" ignore-unresolvable="true"/>
<encryption:string-encryptor id="stringEnc" algorithm="PBEWithMD5AndDES" password="MASTERPASSWORD" />
<bean id="dbProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location">
<value>/WEB-INF/classes/connection.properties</value>
</property>
</bean>
in my applicationcontext.xml i have this :
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/dashboardsupervisor" />
<property name="username" value="root" />
<property name="password" value="1234" />
</bean>
here i am connecting with my database :
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
MySQLRdbHelper rdbHelper = (MySQLRdbHelper)
ctx.getBean("ManagerSupervisor");
What is want is to NOT read the password "1234" from my applicationcontext.xml
and read it from some properties file in my local drive .
as this will be running on different machines and every one have different passwords.
Can i achieve this .
thanks
Yes, you can, and the key to this is Springs PropertyPlaceholderConfigurer.
For example, you create a file on your file system called database.properties, containing your password (note, that you can also add more settings to this file, like username, JDBC url, etc).
jdbc.password=1234
Next, you need to declare a PropertyPlaceholderConfigurer bean and point it to the database.properties file:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>path/to/database.properties</value>
</property>
</bean>
Note that the path is interpreted as a classpath resource, unless it is prefixed with file:.
Finally, replace the configuration of your dataSource bean: replace
<property name="password" value="1234" />
with
<property name="password" value="${jdbc.password}" />
You could use profiles:
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.getEnvironment().setActiveProfiles("dev1");
ctx.load("*Context.xml");
ctx.refresh();
<bean id="database1" profile="dev1"/>
<bean id="database2" profile="dev2">
The best way is to create the data source in application server and configure as below in application.xml
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>YourDSName</value></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
.....
</bean>
I'm trying to get an embedded Derby db running on a Tomcat/Spring application.
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="url" value="jdbc:derby:pepper" />
<property name="initialSize" value="5" />
<property name="maxActive" value="50" />
</bean>
When I run this, I'm getting the following error:
org.apache.commons.dbcp.SQLNestedException:
Cannot create
PoolableConnectionFactory (Database
'WEB-INF/pepper' not found.)
I've tried the pepper folder at both %webapp_root%/pepper and %webapp_root%/WEB-INF/pepper
Suggestions?
If you're deploying a web app to Tomcat, I'd recommend setting up a JNDI connection pool and using Spring's JndiObjectFactoryBean:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/blah"/>
</bean>
I guess you need to replace url with jdbc:derby:pepper;create=true