Loading a .properties file with Spring (Java) - java

I am having an issue with loading a .properties file.
The file is called "businessmessages_en_US.properties" and it is stored in "src/main/resources/config/i18n". I have added "src/main/resources" to the build path and in my spring xml I have created a bean:
<bean name="messageResource" id="messageResource"
class="[package].CustomResourceBundleMessageSourceImpl">
<property name="basename">
<value>classpath*:config/i18n/*.properties</value>
</property>
</bean>
Note that the "basename" property must be a string according to the class
Yet every time I run my program, the logger shoots a message:
01 Jul 2013 09:12:34,267 WARN [package].CustomResourceBundleMessageSourceImpl - ResourceBundle [classpath*:config/i18n/*.properties] not found for MessageSource: Can't find bundle for base name classpath*:config/i18n/*.properties, locale en_US
I need the program to read this file so that the logger can have the correct values. Any help would be greatly appreciated. Thank you!

<context:property-placeholder location="classpath*:*.properties"/>
and then use it like this:
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>

Related

How can i make a Spring bean which can be configured in setters as well constructor dependency?

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

how to use values from external property files in spring xml configuration?

I tryed to pull password from hibernate config to separate properies file.
Initially I had this config:
...
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
...
<property name="username" value=root />
...
After I wrote following
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db.properties</value>
</list>
</property>
</bean>
...
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
...
<property name="username" value="${db.username}" />
...
in db.properties I wrote following:
username=root
I got following trace:
org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: class path resource [db.properties] cannot be opened because it does not exist
file with configurationa and db.properties locates in same folder.
You can ignore the classpath: keyword and just use db.properties in the list.
it working after:
put db.properties to src/main/resources
replace this configuration
${db.username}
with
${username}

Access Spring properties from PropertySource

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

how can i get database password at runtime before connecting to the database

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>

Using JNDI for for my datasource and location of properties files

I want to use jndi in my spring mvc application for 2 things:
datasource settings
store the location of my properties file so I can do a lookup in my code
I actually have 2 applications, 1 is a spring mvc and the other is a spring so I'm planning on using the same jndi settings for both.
Also, the 2 applications run on different contains (tomcat and jetty), I've never used jndi before so I hope I can define this in a single location and have both applications point to the same jndi file (assuming its a file).
So as for #1, my datasource settings in my spring context file are currently:
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/mydb_development"/>
<property name="username" value="devuser1"/>
<property name="password" value="123"/>
<property name="maxActive" value="100"/>
<property name="maxIdle" value="30"/>
<property name="maxWait" value="1000"/>
<property name="defaultAutoCommit" value="true"/>
<property name="removeAbandoned" value="true"/>
<property name="removeAbandonedTimeout" value="60"/>
<property name="testOnBorrow" value="true"/>
<property name="validationQuery" value="SELECT 1"/>
</bean>
Can someone tell me how I can extract this out to use JNDI, confused, is it a separate file that has to be in my class loader, or do I hard code the path in my spring context file?
And as for #2, in my code I am currently loading a properties file that is in my class path like:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream is = classLoader.getResourceAsStream("test.properties");
Now the test.properties file is in my classpath so it works out of the box, but what I want to know/understand is if I could somehow use jndi to lookup the location of the properties file (if that makes sense?) and not have this file in my classpath potentially.
I did google around and I know in spring I can pull in jndi using:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/mysqlDataSource" />
But what I don't understand is, where is the actual file that has the settings? Can it be in a location other than my web.xml file? (my other application again is using spring, but it is a daemon so it doesn't have a web.xml file).
The goal for me is to be able to change the values of the jndi file (like username, passwords, file paths) and NOT have these embedded into a jar. I want to be able to manually edit these files on the production server or dev servers and just restart the container.
I'm kinda rusty with spring but I remember using a PropertyPlaceHolderConfigurer, something like:
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound">
<value>true</value>
</property>
<property name="ignoreUnresolvablePlaceholders">
<value>true</value>
</property>
<property name="locations">
<list>
<value>file:path to your file
</value>
<value>file:path to another file if needed
</value>
</list>
</property>
</bean>
Then you can use the values on the .properties defined on the list directly. i.e. if you have a property like
db.driver=com.mysql.jdbc.Driver
you can use it like
bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="driverClassName" value="${db.driver}"/>
when you want to define a value.
If you want further control over the file, the path to the file itself can be registered on your server and you can look it up through JNDI, changing
file:path to your file
into
file:${propertiesFilePath}
I'm pretty sure you can look up those configuration properties by code too by a normal JNDI lookup.

Categories

Resources